diff --git a/AUTHORS b/AUTHORS
index c3a12fe499b7478498ddf2be897558e71884f731..aa3d2fd53258967e3ad424e1482dc7b9e325a75b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,10 @@
 Oberhuber Tomas <tomas.oberhuber@fjfi.cvut.cz>
-Zabka Vitezslav <zabkavit@fjfi.cvut.cz>
-Vladimir Klement
-Tomáš Sobotík
-Ondřej Székely
-Jiří Kafka
+Zabka Vitezslav <zabkav@gmail.com>
+Vladimir Klement <wlada@post.cz>
+Tomáš Sobotík <sobotik.tomas@gmail.com>
+Ondřej Székely <ondra.szekely@gmail.com>
 Libor Bakajsa
-Jakub KlinkovskĂ˝
+Jakub KlinkovskĂ˝ <klinkjak@fjfi.cvut.cz>
 Vacata Jan
 Heller Martin
 Novotny Matej
diff --git a/CMakeLists.txt b/CMakeLists.txt
old mode 100755
new mode 100644
index 3bbf5b3393b52f3a2556b925e0346441bd9d649a..634c581b203cbd77f1346a1689abc7bc7a1691cb
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,7 +12,7 @@
 # Vladimir Klement
 # Jakub Klinkovsky
 
-cmake_minimum_required( VERSION 3.4 )
+cmake_minimum_required( VERSION 3.5.1 )
 
 project( tnl )
 
@@ -21,31 +21,28 @@ set( tnlVersion "0.1" )
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 include( OptimizeForArchitecture )
-include( UseCodeCoverage )
 
 ####
 # Settings for debug/release version
 #
 if( CMAKE_BUILD_TYPE STREQUAL "Debug")
-    set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Debug/src/TNL )
-    set( PROJECT_TESTS_PATH ${PROJECT_SOURCE_DIR}/Debug/src/Tests )
+    set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Debug/src )
     set( PROJECT_TOOLS_PATH ${PROJECT_SOURCE_DIR}/Debug/bin )
     set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Debug/lib )
     set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Debug/bin )
     set( debugExt -dbg )
 else()
-    set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Release/src/TNL )
-    set( PROJECT_TESTS_PATH ${PROJECT_SOURCE_DIR}/Release/src/Tests )
+    set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Release/src )
     set( PROJECT_TOOLS_PATH ${PROJECT_SOURCE_DIR}/Release/bin )
-    set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/lib)
-    set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/bin)
+    set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/lib )
+    set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/bin )
 endif()
 
 # set Debug/Release options
-set( CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unused-local-typedefs -Wno-unused-variable" )
+set( CMAKE_CXX_FLAGS "-std=c++11 -pthread -Wall -Wno-unused-local-typedefs -Wno-unused-variable" )
 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" )
+set( CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -mtune=native -DNDEBUG" )
+#set( CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -mtune=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" )
@@ -54,7 +51,19 @@ 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..."    )
-   set( CMAKE_CXX_FLAGS "${CXXFLAGS} -DHAVE_ICPC ")
+   set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_ICPC -wd2568 -wd2571 -wd2570")
+   #####
+   #  Ckeck for MIC 
+   #
+   if( WITH_MIC STREQUAL "yes" )
+       message( "Compile MIC support..."    )
+       set( MIC_CXX_FLAGS "-DHAVE_MIC")
+       # build all tests with MIC support
+       set( CXX_TESTS_FLAGS ${CXX_TESTS_FLAGS} -DHAVE_MIC )
+       set( WITH_CUDA "no")
+   else()
+       set( MIC_CXX_FLAGS "")
+   endif( )	
 endif()
 
 #####
@@ -67,12 +76,19 @@ if( WITH_CUDA STREQUAL "yes" )
         set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)
         set(BUILD_SHARED_LIBS ON)
         set(CUDA_SEPARABLE_COMPILATION ON)        
+        # Use the CUDA_HOST_COMPILER environment variable if the user specified it.
+        if( NOT $ENV{CUDA_HOST_COMPILER} STREQUAL "" )
+            message( "-- Setting CUDA_HOST_COMPILER to '$ENV{CUDA_HOST_COMPILER}'" )
+            set( CUDA_HOST_COMPILER $ENV{CUDA_HOST_COMPILER} )
+        else()
+            message( "-- Setting CUDA_HOST_COMPILER to '${CMAKE_CXX_COMPILER}'" )
+            set( CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} )
+        endif()
         set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ;-DHAVE_CUDA)
         # disable false compiler warnings
         #   reference for the -Xcudafe flag: http://stackoverflow.com/questions/14831051/how-to-disable-compiler-warnings-with-nvcc/17095910#17095910
         #   list of possible tokens: http://www.ssl.berkeley.edu/~jimm/grizzly_docs/SSL/opt/intel/cc/9.0/lib/locale/en_US/mcpcom.msg
-        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; -Wno-deprecated-gpu-targets --expt-relaxed-constexpr -Xcudafe "\"--diag_suppress=code_is_unreachable --diag_suppress=implicit_return_from_non_void_function\"")
-        #AddCompilerFlag( "-DHAVE_NOT_CXX11" ) # -U_GLIBCXX_ATOMIC_BUILTINS -U_GLIBCXX_USE_INT128 " )
+        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; -Wno-deprecated-gpu-targets --expt-relaxed-constexpr --expt-extended-lambda -Xcudafe "\"--diag_suppress=code_is_unreachable --diag_suppress=implicit_return_from_non_void_function\"")
         set( ALL_CUDA_ARCHS -gencode arch=compute_20,code=sm_20
                             -gencode arch=compute_30,code=sm_30
                             -gencode arch=compute_32,code=sm_32 
@@ -91,7 +107,7 @@ if( WITH_CUDA STREQUAL "yes" )
                 set( CUDA_ARCH_SOURCE ${PROJECT_SOURCE_DIR}/src/Tools/tnl-cuda-arch.cu)
                 message( "Compiling tnl-cuda-arch ..." )
                 file( MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} )
-                execute_process( COMMAND nvcc ${CUDA_ARCH_SOURCE} -o ${CUDA_ARCH_EXECUTABLE}
+                execute_process( COMMAND nvcc --compiler-bindir ${CUDA_HOST_COMPILER} ${CUDA_ARCH_SOURCE} -o ${CUDA_ARCH_EXECUTABLE}
                                  RESULT_VARIABLE CUDA_ARCH_RESULT
                                  OUTPUT_VARIABLE CUDA_ARCH_OUTPUT
                                  ERROR_VARIABLE CUDA_ARCH_OUTPUT )
@@ -115,9 +131,6 @@ if( WITH_CUDA STREQUAL "yes" )
         set( CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; ${CUDA_ARCH} -D_FORCE_INLINES )
         # 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
@@ -171,6 +184,7 @@ if( WITH_CUDA STREQUAL "yes" )
     endif( CUDA_FOUND )
 endif( WITH_CUDA STREQUAL "yes" )
 
+
 ####
 # Check for OpenMP
 #
@@ -233,7 +247,7 @@ if( ${SYS_TIME_INCLUDE_DIR} STREQUAL "SYS_TIME_INCLUDE_DIR-NOTFOUND" )
     message(  "Missing header file sys/time.h" )
     set( HAVE_SYS_TIME_H "//#define HAVE_SYS_TIME_H 1" )
 else()
-    include_directories( ${SYS_TIME_INCLUDE_DIR}/tnl-${tnlVersion} )
+    #include_directories( ${SYS_TIME_INCLUDE_DIR} )
     set( HAVE_SYS_TIME_H "#define HAVE_SYS_TIME_H 1" )
 endif()
 
@@ -245,7 +259,7 @@ if( ${SYS_RESOURCE_INCLUDE_DIR} STREQUAL "SYS_RESOURCE_INCLUDE_DIR-NOTFOUND" )
     message( "Missing header file sys/time.h" )
     set( HAVE_SYS_RESOURCE_H "//#define HAVE_SYS_RESOURCE_H 1" )
 else()
-    include_directories( ${SYS_RESOURCE_INCLUDE_DIR}/tnl-${tnlVersion} )
+    #include_directories( ${SYS_RESOURCE_INCLUDE_DIR} )
     set( HAVE_SYS_RESOURCE_H "#define HAVE_SYS_RESOURCE_H 1" )
 endif()
 
@@ -257,15 +271,20 @@ if( ${SYS_IOCTL_INCLUDE_DIR} STREQUAL "SYS_IOCTL_INCLUDE_DIR-NOTFOUND" )
     message( "Missing header file sys/time.h" )
     set( HAVE_SYS_IOCTL_H "//#define HAVE_SYS_IOCTL_H 1" )
 else()
-    include_directories( ${SYS_IOCTL_INCLUDE_DIR}/tnl-${tnlVersion} )
+    #include_directories( ${SYS_IOCTL_INCLUDE_DIR} )
     set( HAVE_SYS_IOCTL_H "#define HAVE_SYS_IOCTL_H 1" )
 endif()
 
 if( WITH_TESTS STREQUAL "yes" )
-   find_package( GTest )
-   if( GTEST_FOUND )
-      set( CXX_TESTS_FLAGS "-DHAVE_GTEST" )
-   endif( GTEST_FOUND )
+   enable_testing()
+
+   # build gtest libs
+   include( BuildGtest )
+
+   if( WITH_COVERAGE STREQUAL "yes" AND CMAKE_BUILD_TYPE STREQUAL "Debug" )
+      # enable code coverage reports
+      include( UseCodeCoverage )
+   endif()
 endif( WITH_TESTS STREQUAL "yes" )
 
 find_package( PythonInterp 3 )
@@ -326,9 +345,6 @@ if( OPTIMIZED_VECTOR_HOST_OPERATIONS STREQUAL "yes" )
    AddCompilerFlag( "-DOPTIMIZED_VECTOR_HOST_OPERATIONS " )
 endif()
 
-set( CXX_TEST_FLAGS "-fprofile-arcs -ftest-coverage" )
-set( LD_TEST_FLAGS "-lgcov -coverage" )
-
 set( configDirectory \"${CMAKE_INSTALL_PREFIX}/share/tnl-${tnlVersion}/\")
 set( sourceDirectory \"${PROJECT_SOURCE_DIR}/\" )
 set( testsDirectory \"${PROJECT_TESTS_PATH}/\" )
@@ -336,13 +352,11 @@ CONFIGURE_FILE( "tnlConfig.h.in" "${PROJECT_BUILD_PATH}/TNL/tnlConfig.h" )
 INSTALL( FILES ${PROJECT_BUILD_PATH}/TNL/tnlConfig.h DESTINATION include/tnl-${tnlVersion}/TNL )
 if( PYTHONINTERP_FOUND )
     CONFIGURE_FILE( "Config.py.in" "${PROJECT_BUILD_PATH}/TNL/Config.py" )
-    INSTALL( FILES ${PROJECT_BUILD_PATH}/TNL/Config.py DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/TNL )
-    CONFIGURE_FILE( "python-version.in" "${PROJECT_TOOLS_PATH}/../python-version" )
+    INSTALL( FILES ${PROJECT_BUILD_PATH}/TNL/Config.py DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/TNL )
 endif( PYTHONINTERP_FOUND )
 
 #Nastavime cesty k hlavickovym souborum a knihovnam
 INCLUDE_DIRECTORIES( src )
-INCLUDE_DIRECTORIES( tests )
 INCLUDE_DIRECTORIES( ${PROJECT_BUILD_PATH} )
 LINK_DIRECTORIES( ${LIBRARY_OUTPUT_PATH} )
 
@@ -350,7 +364,10 @@ LINK_DIRECTORIES( ${LIBRARY_OUTPUT_PATH} )
 add_subdirectory( src )
 add_subdirectory( share )
 add_subdirectory( tests )
-add_subdirectory( examples )
+
+if( WITH_EXAMPLES STREQUAL "yes" )
+   add_subdirectory( examples )
+endif()
 
 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Template Numerical Library")
 set(CPACK_PACKAGE_VENDOR "MMG")
diff --git a/Copyright b/Copyright
index 1acdabf71aab5f9fa39db4324b5df03c2d4628f8..5582a49998d29ad3d7552e697c4eeb26a09ea461 100644
--- a/Copyright
+++ b/Copyright
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2004-2016 Tomáš Oberhuber et al.
+Copyright (c) 2004-2017 Tomáš Oberhuber et al.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/INSTALL b/INSTALL
index ab759d74a7ea9dc57225f4f0fac1479dc58e7ac7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1 +0,0 @@
-/usr/local/share/automake-1.11/INSTALL
\ No newline at end of file
diff --git a/README b/README
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f4804b5e42323862dc09b426cf601af825ae6bfd 100644
--- a/README
+++ b/README
@@ -0,0 +1,80 @@
+Installation
+============
+
+    Requirements:
+
+    To install TNL, you need:
+
+    cmake 3.4 or later (https://cmake.org/download/)
+    GNU g++ 4.8 or later (https://gcc.gnu.org/)
+    CUDA 8.0 or later (https://developer.nvidia.com/cuda-downloads)
+
+    For image processing problems, you may optionally install:
+    DCMTK (http://dicom.offis.de/dcmtk.php.en)
+    libpng (http://www.libpng.org/pub/png/libpng.html)
+    libjpeg (http://libjpeg.sourceforge.net/)
+
+    The latest release of TNL can be downloaded as:
+
+    wget tnl-project.org/data/src/tnl-0.1.tar.bz2
+
+    Unpack it as:
+
+    tar xvf tnl-0.1.tar.bz2
+    cd tnl-0.1
+
+    Executing command
+
+    ./install
+
+    will install TNL to a folder ${HOME}/.local . You may change it by
+
+    ./install --prefix=<TNL prefix>
+
+    During the installation, TNL fetches latest version of Gtest and install it only 
+    locally to sub-folders Debug and Release. At the end of the installation, the
+    script is checking if the prefix folder is visible to your bash and your linker.
+    If not, it informs you how to change your ${HOME}/.bashrc file to fix it.
+
+How to write a simple solver
+============================
+
+To implement your own solver:
+
+    Create and go to your working directory
+
+    mkdir MyProblem
+    cd Myproblem
+
+    Execute a command tnl-quickstart
+
+    tnl-quickstart
+
+    Answer the questions as, for example, follows
+
+    TNL Quickstart -- solver generator
+    ----------------------------------
+    Problem name:My Problem
+    Problem class base name (base name acceptable in C++ code):MyProblem
+    Operator name:Laplace
+
+    Write your numerical scheme by editing a file
+
+    Laplace_impl.h
+
+    on lines:
+        34, 141 and 265 for 1D, 2D and 3D problem respectively with explicit time discretization
+        101, 211 and 332 for 1D, 2D and 3D problem respectively with (semi-)implicit time discretization
+    Compile the program by executing
+
+    make
+
+    for CPU version only or 
+   
+    make WITH_CUDA=yes
+
+    for a solver running on both CPU and GPU. Run it on your favourite HW architecture by executing
+
+    ./MyProblem
+
+    and following the printed help.
diff --git a/TODO b/TODO
index 3f427388a1ec4b4ccb2818f3532ca98bb16b0708..089a312dd155e7817f8fc5ab5b3a0c823f832be8 100644
--- a/TODO
+++ b/TODO
@@ -1,19 +1,21 @@
+- pridet execution policy https://github.com/harrism/hemi/blob/master/hemi/execution_policy.h
+- prejmenova Assert na TNL_ASSERT a rozsirit asserce podobne jako v GTest
+- odstranit paramee lazy ze smart pointeru
+
 TODO:
  - implementovat tnlMixedGridBoundaryConditions, kde by se pro kazdou stranu gridu definoval jiny zvlastni typ
    okrajovych podminek
  - dalo by se tim resit i skladani zpetnych a doprednych diferenci u nelinearni difuze, kdy je potreba napr. dopredne diference
    vycislit i na leve a dolni hranici 2D gridu
+   - tohle resit spis primym rozepsanim schematu
 
 TODO:
- - implementovat tuple pro snazsi a snad efektoivnejsi prenos dat na GPU
+ - implementovat tuple pro snazsi a snad efektivnejsi prenos dat na GPU
  - nebylo by nutne definovat pomocne datove structury pro traverser
  - data by se na hostu preskupila do souvisleho bloku dat a ten se prenesl najednou
 
 
 TODO:
- - zrejme bude potreba udrzovat ke kazdemu objektu jeho obraz na GPU/MIC
- - to by zarizovala metoda syncToDevice() napr. kazdy objekt by mel promennou modified, ktera by rikala, jestli se zmenil a zda je nutne ho
-   prekopirovavat
 
 TODO:
  - zavest namespaces
@@ -26,6 +28,11 @@ TODO: CUDA unified memory
 se s nimi pracovat postaru
  - bylo by dobre to obalit unique poinetry, aby se nemusela delat dealokace rucne
 
+TODO: shared pointery
+ - mohli bysme pomoci nich odstranit Shared objekty
+ - asi by bylo lepsi datcounter z shared pointeru primo do array a tento counter by se alokoval az po porvnim sdileni dat
+ - diky tomu by se array mohlo vytvaret i na gpu bez nutnosti dynamicke alokace, jen by nebylo mozne delat bind (nebo nejaky zjednoduseny)
+
 TODO: Mesh
  * vsechny traits zkusit presunout do jednotneho MeshTraits, tj. temer MeshConfigTraits ale pojmenovat jako MeshTraits
  * omezit tnlDimesnionsTag - asi to ale nepujde
diff --git a/build b/build
index cb92740ba414ab96c34f312b5103e709b9093c2c..e3fbfe5e470bb80e09038269423ea2cfe2a0d798 100755
--- a/build
+++ b/build
@@ -2,35 +2,51 @@
 
 TARGET=TNL
 PREFIX=${HOME}/.local
+INSTALL="no"
+ROOT_DIR="."
+DCMTK_DIR="/usr/include/dcmtk"
+BUILD=""
+BUILD_JOBS=""
+CMAKE="cmake"
+CMAKE_ONLY="no"
+HELP="no"
+VERBOSE=""
+
 WITH_CLANG="no"
 WITH_CUDA="yes"
+WITH_CUDA_ARCH="auto"
 WITH_TESTS="yes"
+WITH_COVERAGE="no"
+WITH_EXAMPLES="yes"
 
-WITH_CUDA_ARCH="auto"
-WITH_TEMPLATE_INSTANTIATION="yes"
+WITH_TEMPLATE_INSTANTIATION="no"
 INSTANTIATE_LONG_INT="no"
 INSTANTIATE_INT="yes"
 INSTANTIATE_LONG_DOUBLE="no"
 INSTANTIATE_DOUBLE="yes"
 INSTANTIATE_FLOAT="no"
 OPTIMIZED_VECTOR_HOST_OPERATIONS="no"
-CMAKE="cmake"
-CMAKE_ONLY="no"
-HELP="no"
-VERBOSE=""
-ROOT_DIR="."
-DCMTK_DIR="/usr/include/dcmtk"
-BUILD_JOBS=`grep -c processor /proc/cpuinfo`
 
 for option in "$@"
 do
     case $option in
         --prefix=*                       ) PREFIX="${option#*=}" ;;
+        --install=*                      ) INSTALL="${option#*=}" ;;
+        --root-dir=*                     ) ROOT_DIR="${option#*=}" ;;
+        --dcmtk-dir=*                    ) DCMTK_DIR="${option#*=}" ;;
         --build=*                        ) BUILD="${option#*=}" ;;
+        --build-jobs=*                   ) BUILD_JOBS="${option#*=}" ;;
+        --cmake=*                        ) CMAKE="${option#*=}" ;;
+        --cmake-only=*                   ) CMAKE_ONLY="${option#*=}" ;;
+        --verbose                        ) VERBOSE="VERBOSE=1" ;;
+        --help                           ) HELP="yes" ;;
         --with-clang=*                   ) WITH_CLANG="${option#*=}" ;;
-        --with-tests=*                   ) WITH_TESTS="${option#*=}" ;;
+        --with-mic=*                     ) WITH_MIC="${option#*=}" ;;
         --with-cuda=*                    ) WITH_CUDA="${option#*=}" ;;
         --with-cuda-arch=*               ) WITH_CUDA_ARCH="${option#*=}";;
+        --with-tests=*                   ) WITH_TESTS="${option#*=}" ;;
+        --with-coverage=*                ) WITH_COVERAGE="${option#*=}" ;;
+        --with-examples=*                ) WITH_EXAMPLES="${option#*=}" ;;
         --with-templates-instantiation=* ) WITH_TEMPLATE_INSTANTIATION="${option#*=}" ;;
         --instantiate-long-int=*         ) INSTANTIATE_LONG_INT="${option#*=}" ;;
         --instantiate-int=*              ) INSTANTIATE_INT="${option#*=}" ;;
@@ -44,13 +60,6 @@ do
                                            INSTANTIATE_FLOAT="no"
                                            WITH_CUDA_ARCH="auto" ;;
         --optimize-vector-host-operations=* ) OPTIMIZED_VECTOR_HOST_OPERATIONS="yes" ;;
-        --with-cmake=*                   ) CMAKE="${option#*=}" ;;
-        --build-jobs=*                   ) BUILD_JOBS="${option#*=}" ;;
-        --cmake-only=*                   ) CMAKE_ONLY="${option#*=}" ;;
-        --verbose                        ) VERBOSE="VERBOSE=1" ;;
-        --root-dir=*                     ) ROOT_DIR="${option#*=}" ;;
-        --dcmtk-dir=*                    ) DCMTK_DIR="${option#*=}" ;;
-        --help                           ) HELP="yes" ;;
         *                                ) 
            echo "Unknown option ${option}. Use --help for more information."
            exit 1 ;;
@@ -61,15 +70,18 @@ if test ${HELP} = "yes";
 then
     echo "TNL build options:"
     echo ""
-    echo "   --prefix=PATH                         Prefix for the installation directory. ${HOME}/local by default."
     echo "   --build=Debug/Release                 Build type."
-    echo "   --with-tests=yes/no                   Enable unit tests. 'yes' by default (libcppunit-dev is required)."
+    echo "   --build-jobs=NUM                      Number of processes to be used for the build. It is set to the number of available CPU cores by default."
+    echo "   --prefix=PATH                         Prefix for the installation directory. ${HOME}/local by default."
+    echo "   --install=yes/no                      Enables the installation of TNL files."
+    echo "   --with-mic=yes/no                     Enable MIC (Intel Xeon Phi). 'no' by default (Intel Compiler required)."
     echo "   --with-cuda=yes/no                    Enable CUDA. 'yes' by default (CUDA Toolkit is required)."
-    echo "   --with-cuda-arch=all/auto/30/35/...   Choose CUDA architecture."   
-    echo "   --with-templates-instantiation=yes/no Some TNL templates are precompiled during the build. 'yes' by default."
-    echo "   --full-build                          Instantiate all -- long int indexing, float and long double floating point arithmetics."
-    echo "   --with-cmake=CMAKE                    Path to cmake. 'cmake' by default."
-    echo "   --build-jobs=NUM                      Number of processes to be used for the build. It is set to a number of CPU cores by default."
+    echo "   --with-cuda-arch=all/auto/30/35/...   Choose CUDA architecture. 'auto' by default."
+    echo "   --with-tests=yes/no                   Enable unit tests. 'yes' by default."
+    echo "   --with-coverage=yes/no                Enable code coverage reports for unit tests. 'no' by default (lcov is required)."
+    echo "   --with-examples=yes/no                Compile the 'examples' directory. 'yes' by default."
+    echo "   --with-templates-instantiation=yes/no Precompiles some TNL templates during the build. 'no' by default."
+    echo "   --cmake=CMAKE                         Path to cmake. 'cmake' by default."
     echo "   --verbose                             It enables verbose build."
     echo "   --root-dir=PATH                       Path to the TNL source code root dir."
     echo "   --dcmtk-dir=PATH                      Path to the DCMTK (Dicom Toolkit) root dir."
@@ -89,10 +101,12 @@ echo "Configuring ${BUILD} $TARGET ..."
 ${CMAKE} ${ROOT_DIR} \
          -DCMAKE_BUILD_TYPE=${BUILD} \
          -DCMAKE_INSTALL_PREFIX=${PREFIX} \
+         -DWITH_MIC=${WITH_MIC} \
          -DWITH_CUDA=${WITH_CUDA} \
          -DWITH_CUDA_ARCH=${WITH_CUDA_ARCH} \
          -DWITH_TESTS=${WITH_TESTS} \
-         -DPETSC_DIR=${PETSC_DIR} \
+         -DWITH_COVERAGE=${WITH_COVERAGE} \
+         -DWITH_EXAMPLES=${WITH_EXAMPLES} \
          -DDCMTK_DIR=${DCMTK_DIR} \
          -DWITH_TEMPLATE_INSTANTIATION=${WITH_TEMPLATE_INSTANTIATION} \
          -DINSTANTIATE_FLOAT=${INSTANTIATE_FLOAT} \
@@ -109,21 +123,42 @@ fi
 
 if test ${CMAKE_ONLY} = "yes";
 then
-    exit 1
+    exit 0
 fi
 
-echo "Building ${BUILD} $TARGET using $BUILD_JOBS processors ..."
+if [[ -n ${BUILD_JOBS} ]]; then
+    # override $MAKEFLAGS from parent environment
+    export MAKEFLAGS=-j${BUILD_JOBS}
+elif [[ -z ${MAKEFLAGS} ]]; then
+    # $BUILD_JOBS and $MAKEFLAGS are not set => set default value
+    BUILD_JOBS=$(grep "core id" /proc/cpuinfo | sort -u | wc -l)
+    export MAKEFLAGS=-j${BUILD_JOBS}
+fi
+
+if [[ -n ${BUILD_JOBS} ]]; then
+    echo "Building ${BUILD} $TARGET using $BUILD_JOBS processors ..."
+else
+    # number of processors is unknown - it is encoded in $MAKEFLAGS from parent environment
+    echo "Building ${BUILD} $TARGET ..."
+fi
+
+if [[ "$INSTALL" == "yes" ]]; then
+   # install implies all
+   make_target="install"
+else
+   make_target="all"
+fi
 
-make -j${BUILD_JOBS} ${VERBOSE}
+make ${VERBOSE} $make_target
 if test $? != 0; then
     echo "Error: Build process failed."
     exit 1
 fi
 
 
-if test WITH_TESTS = "yes";
+if test ${WITH_TESTS} = "yes";
 then
-    make -j${BUILD_JOBS} test
+    make test
     if test $? != 0; then
         echo "Error: Some test did not pass successfuly."
     fi
diff --git a/cmake/BuildGtest.cmake b/cmake/BuildGtest.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5567e76c881bdd5359cffeb2c9fa07a40ec40231
--- /dev/null
+++ b/cmake/BuildGtest.cmake
@@ -0,0 +1,45 @@
+# Gtest developers recommend to build the gtest libraries directly from
+# the projects' build systems, see
+# https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+
+#find_package( GTest )
+#if( GTEST_FOUND )
+#   set( CXX_TESTS_FLAGS "${CXX_TESTS_FLAGS} -DHAVE_GTEST" )
+#endif( GTEST_FOUND )
+
+
+# compatibility with the GTest package
+set( GTEST_BOTH_LIBRARIES gtest gtest_main )
+set( CXX_TESTS_FLAGS ${CXX_TESTS_FLAGS} -DHAVE_GTEST )
+
+
+# Download and unpack googletest at configure time
+configure_file(cmake/Gtest.cmake.in googletest-download/CMakeLists.txt)
+execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
+if(result)
+ message(FATAL_ERROR "CMake step for googletest failed: ${result}")
+endif()
+execute_process(COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download )
+if(result)
+ message(FATAL_ERROR "Build step for googletest failed: ${result}")
+endif()
+
+# Prevent overriding the parent project's compiler/linker
+# settings on Windows
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+# Add googletest directly to our build. This defines
+# the gtest and gtest_main targets.
+add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
+                ${CMAKE_BINARY_DIR}/googletest-build)
+
+# The gtest/gtest_main targets carry header search path
+# dependencies automatically when using CMake 2.8.11 or
+# later. Otherwise we have to add them here ourselves.
+if (CMAKE_VERSION VERSION_LESS 2.8.11)
+    include_directories("${gtest_SOURCE_DIR}/include")
+endif()
diff --git a/cmake/Gtest.cmake.in b/cmake/Gtest.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..762cff74ab9f856066a69c97c24fe69bfd076f66
--- /dev/null
+++ b/cmake/Gtest.cmake.in
@@ -0,0 +1,22 @@
+# vim: ft=cmake
+
+# This is a separate template for CMakeLists.txt to build gtest as a separate project
+#
+# Copied from upstream documentation:
+# https://github.com/google/googletest/tree/master/googletest#incorporating-into-an-existing-cmake-project
+
+cmake_minimum_required(VERSION 2.8.2)
+
+project(googletest-download NONE)
+
+include(ExternalProject)
+ExternalProject_Add(googletest
+  GIT_REPOSITORY    https://github.com/google/googletest.git
+  GIT_TAG           master
+  SOURCE_DIR        "${CMAKE_BINARY_DIR}/googletest-src"
+  BINARY_DIR        "${CMAKE_BINARY_DIR}/googletest-build"
+  CONFIGURE_COMMAND ""
+  BUILD_COMMAND     ""
+  INSTALL_COMMAND   ""
+  TEST_COMMAND      ""
+)
diff --git a/cmake/UseCodeCoverage.cmake b/cmake/UseCodeCoverage.cmake
index d66c9a31a224ff35f96df47720eb3d2841812284..0e4b7f46f5c560a6169fdcbf72473517a5973830 100644
--- a/cmake/UseCodeCoverage.cmake
+++ b/cmake/UseCodeCoverage.cmake
@@ -1,31 +1,25 @@
 #http://www.cmake.org/pipermail/cmake/2010-March/036063.html
 
 
-OPTION( ENABLE_CODECOVERAGE "Enable code coverage testing support" )
-
-if ( ENABLE_CODECOVERAGE )
-
-    if ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
-        message( WARNING "Code coverage results with an optimised (non-Debug) build may be misleading" )
-    endif ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
-
-    if ( NOT DEFINED CODECOV_OUTPUTFILE )
-        set( CODECOV_OUTPUTFILE cmake_coverage.output )
-    endif ( NOT DEFINED CODECOV_OUTPUTFILE )
-
-    if ( NOT DEFINED CODECOV_HTMLOUTPUTDIR )
-        set( CODECOV_HTMLOUTPUTDIR coverage_results )
-    endif ( NOT DEFINED CODECOV_HTMLOUTPUTDIR )
-
-    if ( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCXX )
-        find_program( CODECOV_GCOV gcov )
-        find_program( CODECOV_LCOV lcov )
-        find_program( CODECOV_GENHTML genhtml )
-        add_definitions( -fprofile-arcs -ftest-coverage )
-        link_libraries( gcov )
-        set( CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} --coverage )
-        add_custom_target( coverage_init ALL ${CODECOV_LCOV} --base-directory .  --directory ${CMAKE_BINARY_DIR} --output-file ${CODECOV_OUTPUTFILE} --capture --initial )
-        add_custom_target( coverage ${CODECOV_LCOV} --base-directory .  --directory ${CMAKE_BINARY_DIR} --output-file ${CODECOV_OUTPUTFILE} --capture COMMAND genhtml -o ${CODECOV_HTMLOUTPUTDIR} ${CODECOV_OUTPUTFILE} )
-    endif ( CMAKE_COMPILER_IS_GNUCXX )
-
-endif (ENABLE_CODECOVERAGE )
\ No newline at end of file
+if ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
+    message( WARNING "Code coverage results with an optimised (non-Debug) build may be misleading" )
+endif ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
+
+if ( NOT DEFINED CODECOV_OUTPUTFILE )
+    set( CODECOV_OUTPUTFILE cmake_coverage.output )
+endif ( NOT DEFINED CODECOV_OUTPUTFILE )
+
+if ( NOT DEFINED CODECOV_HTMLOUTPUTDIR )
+    set( CODECOV_HTMLOUTPUTDIR coverage_results )
+endif ( NOT DEFINED CODECOV_HTMLOUTPUTDIR )
+
+if ( CMAKE_COMPILER_IS_GNUCXX )
+    find_program( CODECOV_GCOV gcov )
+    find_program( CODECOV_LCOV lcov )
+    find_program( CODECOV_GENHTML genhtml )
+    add_definitions( -fprofile-arcs -ftest-coverage )
+    link_libraries( gcov )
+    set( CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} --coverage )
+    add_custom_target( coverage_init ALL ${CODECOV_LCOV} --base-directory .  --directory ${CMAKE_SOURCE_DIR} --no-external --output-file ${CODECOV_OUTPUTFILE} --capture --initial --quiet )
+    add_custom_target( coverage ${CODECOV_LCOV} --base-directory .  --directory ${CMAKE_SOURCE_DIR} --no-external --output-file ${CODECOV_OUTPUTFILE} --capture --quiet COMMAND genhtml --quiet -o ${CODECOV_HTMLOUTPUTDIR} ${CODECOV_OUTPUTFILE} )
+endif ( CMAKE_COMPILER_IS_GNUCXX )
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
old mode 100755
new mode 100644
index 0f00654e037cfb1ab253fa4276a57fc1f0f25126..dca68ee58a2075836a177be031be115907577cc8
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,5 +1,15 @@
 add_subdirectory( heat-equation )
+add_subdirectory( transport-equation )
 add_subdirectory( navier-stokes )
-add_subdirectory( advection )
+
+#add_subdirectory( mean-curvature-flow )
+#add_subdirectory( hamilton-jacobi )
+#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( inviscid-flow )
 #add_subdirectory( mean-curvature-flow )
+
diff --git a/examples/advection/CMakeLists.txt b/examples/advection/CMakeLists.txt
deleted file mode 100644
index a09abadcdf99acf50e41f0909dfe02f4dfc31ea9..0000000000000000000000000000000000000000
--- a/examples/advection/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644
index 144567e727f775f6341824cbbd62fd6449462df2..0000000000000000000000000000000000000000
--- a/examples/advection/LaxFridrichs.h
+++ /dev/null
@@ -1,242 +0,0 @@
-#ifndef LaxFridrichs_H
-#define LaxFridrichs_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-      Real tau;
-      Real artificalViscosity;
-      MeshFunctionType advectionSpeedX;
-      MeshFunctionType advectionSpeedY;
-      MeshFunctionType advectionSpeedZ;
-
-      void setAdvectionSpeedZ(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedZ.bind(advectionSpeed);
-      }
-
-      void setAdvectionSpeedY(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedY.bind(advectionSpeed);
-      }
-
-      void setAdvectionSpeedX(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedX.bind(advectionSpeed);
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static String 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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-      Real tau;
-      Real artificalViscosity;
-      MeshFunctionType advectionSpeedX;
-      MeshFunctionType advectionSpeedY;
-      MeshFunctionType advectionSpeedZ;
-
-
-      void setAdvectionSpeedZ(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedZ.bind(advectionSpeed);
-      }
-
-
-      void setAdvectionSpeedY(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedY.bind(advectionSpeed);
-      }
-
-
-      void setAdvectionSpeedX(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedX.bind(advectionSpeed);
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static String 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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-      Real tau;
-      Real artificalViscosity;
-      MeshFunctionType advectionSpeedX;
-      MeshFunctionType advectionSpeedY;
-      MeshFunctionType advectionSpeedZ;
-
-      void setAdvectionSpeedZ(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedZ.bind(advectionSpeed);
-      }
-
-
-      void setAdvectionSpeedY(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedY.bind(advectionSpeed);
-      }
-
-
-      void setAdvectionSpeedX(MeshFunctionType& advectionSpeed)
-      {
-	   this->advectionSpeedX.bind(advectionSpeed);
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static String 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;
-};
-
-} // namespace TNL
-
-
-#include "LaxFridrichs_impl.h"
-
-#endif	/* LaxFridrichs_H */
diff --git a/examples/advection/LaxFridrichs_impl.h b/examples/advection/LaxFridrichs_impl.h
deleted file mode 100644
index 05aafd41f46360db646847164a50021d951b4659..0000000000000000000000000000000000000000
--- a/examples/advection/LaxFridrichs_impl.h
+++ /dev/null
@@ -1,357 +0,0 @@
-#ifndef LaxFridrichs_IMPL_H
-#define LaxFridrichs_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichs< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichs< " ) +
-          MeshType::getType() + ", " +
-          TNL::getType< Real >() + ", " +
-          TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichs< Meshes::Grid< 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 >(); 
-   return   (0.5 / this->tau ) * this->artificalViscosity *
-	    ( u[ west ]- 2.0 * u[ center ] + u[ east ] )
-            - (this->advectionSpeedX [ east ] * u[ east ] - this->advectionSpeedX [ west ] * u[west] ) * hxInverse * 0.5;
-
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichs< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichs< " ) +
-          MeshType::getType() + ", " +
-          TNL::getType< Real >() + ", " +
-          TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichs< Meshes::Grid< 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 >(); 
-   return ( 0.25 / this->tau ) * this->artificalViscosity * 
-          ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4 * u[ center ] ) -
-          (this->advectionSpeedX [ east ] * u[ east ] - this->advectionSpeedX [ west ] * u[ west] ) * hxInverse * 0.5 - 
-          (this->advectionSpeedY [ north ] * u[ north ] - this->advectionSpeedY [ south ] * u[ south ] ) * hyInverse * 0.5;
-
-
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichs< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichs< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichs< Meshes::Grid< 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
-   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
-   const RealType& hzInverse = 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 ( (1.0/6.0) / this->tau ) * this->artificalViscosity * 
-          ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u [ down ] - 6 * u[ center ] ) -
-          (this->advectionSpeedX [ east ] * u[ east ] - this->advectionSpeedX [ west ] * u[ west] ) * hxInverse * 0.5 - 
-          (this->advectionSpeedY [ north ] * u[ north ] - this->advectionSpeedY [ south ] * u[ south ] ) * hyInverse * 0.5 -
-          (this->advectionSpeedZ [ up ] * u[ up ] - this->advectionSpeedZ [ down ] * u[ down ] ) * hzInverse * 0.5;
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< Meshes::Grid< 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< Meshes::Grid< 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 );*/
-}
-
-} // namespace TNL
-
-#endif	/* LaxFridrichsIMPL_H */
-
diff --git a/examples/advection/advection.cpp b/examples/advection/advection.cpp
deleted file mode 100644
index 374d4714086168f7ebf1ed2a62664c4aaae0c4b7..0000000000000000000000000000000000000000
--- a/examples/advection/advection.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "advection.h"
diff --git a/examples/advection/advection.cu b/examples/advection/advection.cu
deleted file mode 100644
index 374d4714086168f7ebf1ed2a62664c4aaae0c4b7..0000000000000000000000000000000000000000
--- a/examples/advection/advection.cu
+++ /dev/null
@@ -1 +0,0 @@
-#include "advection.h"
diff --git a/examples/advection/advection.h b/examples/advection/advection.h
deleted file mode 100644
index f53233aeb773865cd4cdaed8a319e35e4765d705..0000000000000000000000000000000000000000
--- a/examples/advection/advection.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#include <TNL/tnlConfig.h>
-#include <TNL/Solvers/Solver.h>
-#include <TNL/Solvers/BuildConfigTags.h>
-#include <TNL/Operators/DirichletBoundaryConditions.h>
-#include <TNL/Operators/NeumannBoundaryConditions.h>
-#include <TNL/Functions/Analytic/Constant.h>
-#include "advectionProblem.h"
-#include "LaxFridrichs.h"
-#include "advectionRhs.h"
-#include "advectionBuildConfigTag.h"
-#include "Riemann1DBoundaryConditions.h"
-#include "Riemann2DBoundaryConditions.h"
-
-using namespace TNL;
-
-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( Config::ConfigDescription & config )
-      {
-         config.addDelimiter( "advection settings:" );
-         config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
-            config.addEntryEnum< String >( "dirichlet" );
-            config.addEntryEnum< String >( "neumann" );
-            config.addEntryEnum< String >( "riemann1D" );
-            config.addEntryEnum< String >( "riemann2D" );
-         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< String >( "begin", "choose begin type", "sin");
-	    config.addEntryEnum< String >( "exp");
-	    config.addEntryEnum< String >( "exp_square");
-	    config.addEntryEnum< String >( "square");
-	    config.addEntryEnum< String >( "riemann");
-	 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< double >( "advection-speedZ", "This sets value of advection speed in Z direction (default 1)" , 1.0);
-	 config.addEntry< String >( "move", "choose movement type", "advection");
-	    config.addEntryEnum< String >( "advection");
-	    config.addEntryEnum< String >( "rotation");
-	 config.addEntry< int >( "dimension", "choose movement typeproblem dimension", 1);
-	    config.addEntryEnum< int >( 1 );
-	    config.addEntryEnum< int >( 2 );
-            config.addEntryEnum< int >( 3 );
-	 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 Config::ParameterContainer & parameters )
-      {
-          enum { Dimensions = MeshType::getMeshDimensions() };
-          typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator;
-          typedef advectionRhs< MeshType, Real > RightHandSide;
-          typedef Containers::StaticVector < 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 Vector.
-          */
-          String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
-          if( parameters.checkParameter( "boundary-conditions-constant" ) )
-          {
-             typedef Functions::Analytic::Constant< Dimensions, Real > Constant;
-             if( boundaryConditionsType == "dirichlet" )
-             {
-                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-                typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-                SolverStarter solverStarter;
-                return solverStarter.template run< Problem >( parameters );
-             }
-             typedef Operators::NeumannBoundaryConditions< MeshType, Constant, Real, Index > BoundaryConditions;
-             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          typedef Functions::MeshFunction< MeshType > MeshFunction;
-	  if( boundaryConditionsType == "dirichlet" )
-          {
-             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "riemann1D" )
-          {
-             typedef Operators::Riemann1DBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "riemann2D" )
-          {
-             typedef Operators::Riemann2DBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "neumann" )
-          {
-             typedef Operators::NeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
-             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-      return true;}
-};
-
-int main( int argc, char* argv[] )
-{
-   Solvers::Solver< 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
deleted file mode 100644
index 98371b43a3fce8743b7945bbec10ef04ce0d219c..0000000000000000000000000000000000000000
--- a/examples/advection/advectionBuildConfigTag.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef advectionBUILDCONFIGTAG_H_
-#define advectionBUILDCONFIGTAG_H_
-
-#include <TNL/Solvers/BuildConfigTags.h>
-
-namespace TNL {
-
-class advectionBuildConfigTag{};
-
-namespace Solvers {
-
-/****
- * Turn off support for float and long double.
- */
-template<> struct ConfigTagReal< advectionBuildConfigTag, float > { enum { enabled = false }; };
-template<> struct ConfigTagReal< advectionBuildConfigTag, long double > { enum { enabled = false }; };
-
-/****
- * Turn off support for short int and long int indexing.
- */
-template<> struct ConfigTagIndex< advectionBuildConfigTag, short int >{ enum { enabled = false }; };
-template<> struct ConfigTagIndex< advectionBuildConfigTag, long int >{ enum { enabled = false }; };
-
-/****
- * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
- */
-
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< advectionBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ConfigTagDimensions< advectionBuildConfigTag, Dimensions >::enabled  &&
-                         ConfigTagReal< advectionBuildConfigTag, Real >::enabled &&
-                         ConfigTagDevice< advectionBuildConfigTag, Device >::enabled &&
-                         ConfigTagIndex< advectionBuildConfigTag, Index >::enabled }; };
-
-/****
- * Please, chose your preferred time discretisation  here.
- */
-template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
-template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
-template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
-
-/****
- * Only the Runge-Kutta-Merson solver is enabled by default.
- */
-template<> struct ConfigTagExplicitSolver< advectionBuildConfigTag, Solvers::ExplicitEulerSolverTag >{ enum { enabled = true }; };
-
-} // namespace Solvers
-} // namespace TNL
-
-#endif /* advectionBUILDCONFIGTAG_H_ */
diff --git a/examples/advection/advectionProblem_impl.h b/examples/advection/advectionProblem_impl.h
deleted file mode 100644
index 93c3263051b6ab222e6020837a97f3e85fe5fa37..0000000000000000000000000000000000000000
--- a/examples/advection/advectionProblem_impl.h
+++ /dev/null
@@ -1,598 +0,0 @@
-#ifndef advectionPROBLEM_IMPL_H_
-#define advectionPROBLEM_IMPL_H_
-
-#include <TNL/FileName.h>
-#include <TNL/Matrices/MatrixSetter.h>
-#include <TNL/Solvers/PDE/ExplicitUpdater.h>
-#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
-#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
-
-namespace TNL {
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getTypeStatic()
-{
-   return String( "advectionProblem< " ) + Mesh :: getTypeStatic() + " >";
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getPrologHeader() const
-{
-   return String( "advection" );
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-void
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-writeProlog( Logger& logger, const Config::ParameterContainer& 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 MeshPointer& meshPointer,
-       const Config::ParameterContainer& parameters,
-       const String& prefix )
-{
-   if( ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ||
-       ! this->rightHandSidePointer->setup( parameters, prefix + "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 MeshPointer& 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 MeshPointer& mesh,
-          DofVectorPointer& dofVector )
-{
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-bool
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setInitialCondition( const Config::ParameterContainer& parameters,
-                     const MeshPointer& mesh,
-                     DofVectorPointer& dofs,
-                     MeshDependentDataPointer& meshDependentData )
-{
-   typedef typename MeshType::Cell Cell;
-   int dimensions = parameters.getParameter< int >( "dimension" );
-   int count = mesh->template getEntitiesCount< Cell >();
-   int inverseSquareCount = std::sqrt(count);
-   int inverseCubeCount = std::pow(count, (1.0/3.0));
-   const RealType& size = parameters.getParameter< RealType >( "realSize" ) / ::pow(count, 1.0/dimensions);
-   const String& beginChoice = parameters.getParameter< String >( "begin" );
-   Containers::Vector < RealType, DeviceType, IndexType > data1;
-   data1.setSize(count);
-   this->analyt.bind(mesh,data1);
-   this->dimension = dimensions;
-   this->choice = beginChoice;
-   this->size = size;
-   this->schemeSize =parameters.getParameter< RealType >( "realSize" );
-   if (beginChoice == "square")
-      {
-	   if (dimensions == 1)
-	       {
-		   ( *dofs )[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			if ((i>0.4*count) && (i<0.5*count)) ( *dofs )[i]=1; else ( *dofs )[i]=0;
-		   };
-		   ( *dofs )[count-1] = 0;
-		}
-	    else if (dimensions == 2)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-                      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			if ((i>0.4*inverseSquareCount) && (i<0.5*inverseSquareCount) && (j>0.4*inverseSquareCount) && (j<0.5*inverseSquareCount))
-                        ( *dofs )[i * inverseSquareCount + j]=1; else ( *dofs)[i * inverseSquareCount + j]=0;
-		      };
-		}
-           else if (dimensions == 3)
-	       {
-		   for (IndexType i = 0; i < inverseCubeCount-1; i++)
-                      for (IndexType j = 0; j < inverseCubeCount-1; j++)
-                         for (IndexType k = 0; k < inverseCubeCount-1; k++)
-		           {
-			     if ((i>0.4*inverseCubeCount) && (i<0.5*inverseCubeCount) && (k>0.4*inverseCubeCount) && (k<0.5*inverseCubeCount) && (j>0.4*inverseCubeCount) && (j<0.5*inverseCubeCount))
-                             ( *dofs )[i * std::pow(inverseCubeCount,3) + j * inverseCubeCount + k]=1; else ( *dofs)[i * std::pow(inverseCubeCount,3) + j * inverseCubeCount + k]=0;
-		           };
-		};
-       }
-   else if (beginChoice == "exp_square")
-      {
-	   RealType constantFunction;
-	   if (dimensions == 1)
-	       {
-		   ( *dofs )[0] = 0;
-		   RealType expValue;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			expValue = std::exp(-std::pow(10/(size*count)*(size*i-0.2*size*count),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)
-	       {
-		   RealType expValue;
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-                      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			expValue = std::exp(-std::pow(10/(size*inverseSquareCount)*(size*i-0.2*size*inverseSquareCount),2)-std::pow(10/(size*inverseSquareCount)*(size*j-0.2*size*inverseSquareCount),2));
-			if ((i>0.4*inverseSquareCount) && (i<0.5*inverseSquareCount) && (j>0.4*inverseSquareCount) && (j<0.5*inverseSquareCount))
-                        constantFunction=1; else constantFunction=0;
-			if (expValue>constantFunction) (* dofs )[i * inverseSquareCount + j] = expValue; else (* dofs )[i * inverseSquareCount + j]
-                         = constantFunction;
-		      };
-		}
-            else if (dimensions == 3)
-	       {
-		   RealType expValue;
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-                      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-                         for (IndexType k = 0; k < inverseSquareCount-1; k++)
-		         {
-			   expValue = std::exp(-std::pow(10/(size*inverseCubeCount)*(size*i-0.2*size*inverseCubeCount),2)-std::pow(10/(size*inverseCubeCount)*(size*j-0.2*size*inverseCubeCount),2)-std::pow(10/(size*inverseCubeCount)*(size*k-0.2*size*inverseCubeCount),2));
-			   if ((i>0.4*inverseCubeCount) && (i<0.5*inverseCubeCount) && (j>0.4*inverseCubeCount) && (j<0.5*inverseCubeCount)&& (k>0.4*inverseCubeCount) && (k<0.5*inverseCubeCount))
-                           constantFunction=1; else constantFunction=0;
-			   if (expValue>constantFunction) (* dofs )[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = expValue; else (* dofs )[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k]
-                            = constantFunction;
-		      };
-		};
-       }
-   else if (beginChoice == "exp")
-      {
-	   if (dimensions == 1)
-	      {
-		   ( *dofs )[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			( *dofs )[i] = std::exp(-std::pow(10/(size*count)*(size*i-0.2*size*count),2));
-		   };
-		   ( *dofs )[count-1] = 0;
-		}
-	    else if (dimensions == 2)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			   ( *dofs )[i * inverseSquareCount + j] = std::exp(-std::pow(10/(size*inverseSquareCount)*(size*i-0.2*size*inverseSquareCount),2)-std::pow(10/(size*inverseSquareCount)*(size*j-0.2*size*inverseSquareCount),2));
-		      };
-		}
-             else if (dimensions == 3)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		         for (IndexType k = 0; k < inverseSquareCount-1; k++)
-		         {
-			      ( *dofs )[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = std::exp(-std::pow(10/(size*inverseCubeCount)*(size*i-0.2*size*inverseCubeCount),2)-std::pow(10/(size*inverseCubeCount)*(size*j-0.2*size*inverseCubeCount),2) - std::pow(10/(size*inverseCubeCount)*(size*k-0.2*size*inverseCubeCount),2));
-		         };
-		};
-     }
-   else if (beginChoice == "riemann")
-      {
-	   if (dimensions == 1)
-	      {
-		   ( *dofs )[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			if (i < 0.5 * count ) ( *dofs )[i] = 1; else
-                        ( *dofs )[i] = 0;
-		   };
-		   ( *dofs )[count-1] = 0;
-		}
-	    else if (dimensions == 2)
-	       {
-		   for (IndexType i = 1; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 1; j < inverseSquareCount-1; j++)
-		      {
-			   if (i < 0.5*inverseSquareCount && j < 0.5*inverseSquareCount) ( *dofs )[i * inverseSquareCount + j] = 1; else
-                           ( *dofs )[i * inverseSquareCount + j] = 0;
-		      };
-		}
-	    else if (dimensions == 3)
-	       {
-		   for (IndexType i = 1; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 1; j < inverseSquareCount-1; j++)
-		         for (IndexType k = 1; k < inverseSquareCount-1; k++)
-		         {
-			      if (i < 0.5*inverseSquareCount && j < 0.5*inverseSquareCount && k < 0.5*inverseSquareCount) ( *dofs )[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = 1; else
-                              ( *dofs )[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = 0;
-		         };
-		};
-     };
-   //setting velocity field   
-   /*const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
-   if( ! dofs.load( initialConditionFile ) )
-   {
-      std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
-      return false;
-   }
-   return true;*/
-   ( *dofs ).save( "dofs.tnl" );
-   String velocityType = parameters.getParameter< String >( "move" );
-   RealType artificalViscosity = parameters.getParameter< RealType >( "artifical-viscosity" );
-   differentialOperatorPointer->setViscosity(artificalViscosity);
-   Containers::Vector < RealType, DeviceType, IndexType > data;
-   data.setSize(3*count);
-   ( *velocityX).bind(mesh, data, 0);
-   ( *velocityY).bind(mesh, data, count);
-   ( *velocityZ).bind(mesh, data, 2*count);
-   RealType advectionSpeedX = parameters.getParameter< RealType >( "advection-speedX" );
-   RealType advectionSpeedY = parameters.getParameter< RealType >( "advection-speedY" );
-   RealType advectionSpeedZ = parameters.getParameter< RealType >( "advection-speedZ" );
-   this->speedX =advectionSpeedX;
-   this->speedY =advectionSpeedY;
-   this->speedZ =advectionSpeedZ;
-   if (velocityType == "advection")
-   {
-      for (IndexType i = 0; i<count; i++)
-         {
-            ( *velocityX) [i] = advectionSpeedX;
-            ( *velocityY) [i] = advectionSpeedY;
-            ( *velocityZ) [i] = advectionSpeedZ;
-         };
-   }
-   else if (velocityType == "rotation")
-   {
-      RealType radius;
-      if(dimensions == 2)
-         for(IndexType i = 0; i<count; i++)
-            {
-               radius = ::sqrt(::pow(i/inverseSquareCount - (inverseSquareCount/2.0), 2) + std::pow(i%inverseSquareCount - (inverseSquareCount/2.0), 2))/inverseSquareCount;
-               if ( radius == 0 ) {( *velocityX) [i] = 0; ( *velocityY) [i] = 0;} else {
-               (* velocityX) [i] = advectionSpeedX * radius * std::sin(std::atan(1) * 4 * (i/inverseSquareCount-inverseSquareCount/2.0) / inverseSquareCount);
-               (* velocityY) [i] = advectionSpeedX * radius * std::sin( (-1) * std::atan(1) * 4 * (i%inverseSquareCount-inverseSquareCount/2.0) / inverseSquareCount);
-               }
-            }
-/*       else if(dimensions == 3)
-          for(IndexType i = 0; i<count; i++)
-             {
-               radius = ::sqrt(::pow(i/inverseCubeCount - (inverseCubeCount/2.0), 2) + std::pow(i%inverseCubeCount - (inverseCubeCount/2.0), 2))/inverseCubeCount;
-               if ( radius == 0 ) {( *velocityX) [i] = 0; ( *velocityY) [i] = 0; ( *velocityZ)[i] = 0; } else {
-               (* velocityX) [i] = advectionSpeedX * radius * std::sin(std::atan(1) * 4 * (i+(std::pow(inverseCubeCount,2))/inverseCubeCount-inverseCubeCount/2.0) / inverseCubeCount);
-               //(* velocityY) [i] = advectionSpeedX * radius * std::sin( (-1) * std::atan(1) * 4 * (i%(std::pow(inverseCubeCount,2))%inverseCubeCount-inverseCubeCount/2.0) / inverseCubeCount);
-               //(* velocityZ) [i] = advectionspeedX * radius * std::sin( (-1) * std::atan(1) * 4 * (i/(std::pow(inverseCubeCount,2))-inverseCubeCount/2.0) / inverseCubeCount);
-               }
-             }*/
-   };
-   differentialOperatorPointer->setAdvectionSpeedX((* velocityX));      
-   differentialOperatorPointer->setAdvectionSpeedY((* velocityY));
-   differentialOperatorPointer->setAdvectionSpeedZ((* velocityZ));
-   return true;
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-   template< typename Matrix >
-bool
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setupLinearSystem( const MeshPointer& mesh,
-                   Matrix& matrix )
-{
-   const IndexType dofs = this->getDofs( mesh );
-   typedef typename Matrix::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   SharedPointer< CompressedRowsLengthsVectorType > rowLengths;
-   if( ! rowLengths->setSize( dofs ) )
-      return false;
-   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh,
-                                                                          differentialOperatorPointer,
-                                                                          boundaryConditionPointer,
-                                                                          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 MeshPointer& mesh,
-              DofVectorPointer& dofs,
-              MeshDependentDataPointer& meshDependentData )
-{
-   std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
-   this->bindDofs( mesh, dofs );
-   FileName fileNameU;
-   fileNameU.setFileNameBase( "u-" );
-   fileNameU.setExtension( "tnl" );
-   fileNameU.setIndex( step );
-   if( ! dofs->save( fileNameU.getFileName() ) )
-      return false;
-   FileName fileNameAnalyt;
-   fileNameAnalyt.setFileNameBase( "a-" );
-   fileNameAnalyt.setExtension( "tnl" );
-   fileNameAnalyt.setIndex( step );
-   if( ! analyt.save( fileNameAnalyt.getFileName() ) )
-      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 MeshPointer& mesh,
-                DofVectorPointer& _u,
-                DofVectorPointer& _fu,
-                MeshDependentDataPointer& meshDependentData )
-{
-   step++;
-   typedef typename MeshType::Cell Cell;
-   int count = mesh->template getEntitiesCount< typename MeshType::Cell >();
-   int inverseSquareCount = std::sqrt(count);
-   int inverseCubeCount = std::pow(count, (1.0/3.0));
-   if (tau > 10e-9)
-      {
-   if (this->choice == "square")
-      {
-	   if (dimension == 1)
-	       {
-		   this->analyt[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			if ((i - step * tau * (count/this->schemeSize) * this -> speedX>0.4*count) && (i - step * tau * (count/this->schemeSize) * this -> speedX<0.5*count)) analyt[i]=1; else analyt[i]=0;
-		   };
-		   this->analyt[count-1] = 0;
-		}
-	    else if (dimension == 2)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-                      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			if ((i - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedX>0.4*inverseSquareCount) && (i - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedX<0.5*inverseSquareCount) 
-                         && (j - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedY>0.4*inverseSquareCount) && (j - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedY<0.5*inverseSquareCount))
-                        analyt[i * inverseSquareCount + j]=1; else analyt[i * inverseSquareCount + j]=0;
-		      };
-		}
-	    else if (dimension == 3)
-	       {
-		   for (IndexType i = 0; i < inverseCubeCount-1; i++)
-                      for (IndexType j = 0; j < inverseCubeCount-1; j++)
-                         for (IndexType k = 0; k < inverseCubeCount-1; k++)
-		         {
-			   if ((i - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedX>0.4*inverseCubeCount) && (i - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedX<0.5*inverseCubeCount) 
-                            && (j - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedY>0.4*inverseCubeCount) && (j - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedY<0.5*inverseCubeCount)
-                            && (k - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedZ>0.4*inverseCubeCount) && (k - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedZ<0.5*inverseCubeCount))
-                           analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k]=1; else analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k]=0;
-		         };
-		};
-       }
-   else if (this->choice == "exp_square")
-      {
-	   RealType constantFunction;
-	   if (dimension == 1)
-	       {
-		   this->analyt[0] = 0;
-		   RealType expValue;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			expValue = std::exp(-std::pow(10/(size*count)*(size*i-0.2*size*count)-step * 10 * tau * this->speedX,2));
-			if ((i - step * tau * (count/this->schemeSize) * this -> speedX>0.4*count) && (i - step * tau * (count/this->schemeSize) * this -> speedX<0.5*count)) constantFunction=1; else constantFunction=0;
-			if (expValue>constantFunction) this->analyt[i] = expValue; else this->analyt[i] = constantFunction;
-		   };
-		   this->analyt[count-1] = 0;
-		}
-	    else if (dimension == 2)
-	       {
-		   RealType expValue;
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-                      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			expValue = std::exp(-std::pow(10/(size*inverseSquareCount)*(size*i-0.2*size*inverseSquareCount)-step * 10 * tau * this->speedX,2)-std::pow(10/(size*inverseSquareCount)*(size*j-0.2*size*inverseSquareCount)-step * 10 * tau * this->speedY,2));
-			if ((i - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedX>0.4*inverseSquareCount) && (i - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedX<0.5*inverseSquareCount) 
-                         && (j - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedY>0.4*inverseSquareCount) && (j - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedY<0.5*inverseSquareCount))
-                        constantFunction=1; else constantFunction=0;
-			if (expValue>constantFunction) this->analyt[i * inverseSquareCount + j] = expValue; else this->analyt[i * inverseSquareCount + j]
-                         = constantFunction;
-		      };
-		}
-	    else if (dimension == 3)
-	       {
-		   RealType expValue;
-		   for (IndexType i = 0; i < inverseCubeCount-1; i++)
-                      for (IndexType j = 0; j < inverseCubeCount-1; j++)
-                         for (IndexType k = 0; k < inverseCubeCount-1; k++)
-		         {
-			   expValue = std::exp(-std::pow(10/(size*inverseCubeCount)*(size*k-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedX,2)-std::pow(10/(size*inverseCubeCount)*(size*j-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedY,2)-std::pow(10/(size*inverseCubeCount)*(size*i-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedZ,2));
-			   if ((i - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedX>0.4*inverseCubeCount) && (i - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedX<0.5*inverseCubeCount) 
-                            && (j - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedY>0.4*inverseCubeCount) && (j - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedY<0.5*inverseCubeCount)
-                            && (k - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedZ>0.4*inverseCubeCount) && (k - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedZ<0.5*inverseCubeCount))
-                           constantFunction=1; else constantFunction=0;
-			   if (expValue>constantFunction) this->analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = expValue; else this->analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k]
-                            = constantFunction;
-		         };
-		};
-       }
-   else if (this->choice == "exp")
-      {
-	   if (dimension == 1)
-	      {
-		   this->analyt[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			this->analyt[i] = std::exp(-std::pow(10/(size*count)*(size*i-0.2*size*count)-step * 10 * tau * this->speedX,2));
-		   };
-		   this->analyt[count-1] = 0;
-		}
-	    else if (dimension == 2)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			   this->analyt[i * inverseSquareCount + j] = std::exp(-std::pow(10/(size*inverseSquareCount)*(size*i-0.2*size*inverseSquareCount)-step * 10 * tau * this->speedX,2)-std::pow(10/(size*inverseSquareCount)*(size*j-0.2*size*inverseSquareCount)-step * 10 * tau * this->speedY,2));
-		      };
-		}
-	    else if (dimension == 3)
-	       {
-		   for (IndexType i = 0; i < inverseCubeCount-1; i++)
-		      for (IndexType j = 0; j < inverseCubeCount-1; j++)
-		         for (IndexType k = 0; k < inverseCubeCount-1; k++)
-		         {
-			      this->analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = std::exp(-std::pow(10/(size*inverseCubeCount)*(size*i-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedX,2)-std::pow(10/(size*inverseCubeCount)*(size*j-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedY,2)-std::pow(10/(size*inverseCubeCount)*(size*k-0.2*size*inverseCubeCount)-step * 10 * tau * this->speedZ,2));
-		         };
-		};
-     }
-   else if (this->choice == "riemann")
-      {
-	   if (dimension == 1)
-	      {
-		   this->analyt[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			if (i - step * tau * (count/this->schemeSize) * this -> speedX < 0.5 * count ) this->analyt[i] = 1; else
-                        this->analyt[i] = 0;
-		   };
-		   this->analyt[count-1] = 0;
-		}
-	    else if (dimension == 2)
-	       {
-		   for (IndexType i = 0; i < inverseSquareCount-1; i++)
-		      for (IndexType j = 0; j < inverseSquareCount-1; j++)
-		      {
-			   if (i - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedX < 0.5*inverseSquareCount && 
-                               j - step * tau * (inverseSquareCount/this->schemeSize) * this -> speedY < 0.5*inverseSquareCount) 
-                              this->analyt[i * inverseSquareCount + j] = 1; 
-                           else
-                              this->analyt[i * inverseSquareCount + j] = 0;
-		      };
-		}
-	    else if (dimension == 3)
-	       {
-		   for (IndexType i = 0; i < inverseCubeCount-1; i++)
-		      for (IndexType j = 0; j < inverseCubeCount-1; j++)
-		         for (IndexType k = 0; k < inverseCubeCount-1; k++)
-		         {
-			   if (i - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedX < 0.5*inverseCubeCount && 
-                               j - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedY < 0.5*inverseCubeCount &&
-                               k - step * tau * (inverseCubeCount/this->schemeSize) * this -> speedZ < 0.5*inverseCubeCount) 
-                              this->analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = 1; 
-                           else
-                              this->analyt[i * std::pow(inverseCubeCount,2) + j * inverseCubeCount + k] = 0;
-		         };
-		};
-     };
-     };
-   /*
-   cout << step << endl;
-   cout << tau << endl;
-   cout << this->speedX << endl;
-   cout << step * 10 * tau * this->speedX<< endl;*/
-   this->bindDofs( mesh, _u );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
-   SharedPointer< MeshFunctionType > u( mesh, _u ); 
-   SharedPointer< MeshFunctionType > fu( mesh, _fu );
-   differentialOperatorPointer->setTau(tau); 
-   explicitUpdater.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           this->differentialOperatorPointer,
-                                                           this->boundaryConditionPointer,
-                                                           this->rightHandSidePointer,
-                                                           u,
-                                                           fu );
-/*   BoundaryConditionsSetter< 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 MeshPointer& mesh,
-                      DofVectorPointer& _u,
-                      Matrix& matrix,
-                      DofVectorPointer& b,
-                      MeshDependentDataPointer& meshDependentData )
-{
-   /*LinearSystemAssembler< Mesh,
-                             MeshFunctionType,
-                             DifferentialOperator,
-                             BoundaryCondition,
-                             RightHandSide,
-                             BackwardTimeDiscretisation,
-                             Matrix,
-                             DofVectorType > systemAssembler;
-
-   MeshFunction< Mesh > u( mesh, _u );
-   systemAssembler.template assembly< typename Mesh::Cell >( time,
-                                                             tau,
-                                                             mesh,
-                                                             this->differentialOperator,
-                                                             this->boundaryCondition,
-                                                             this->rightHandSide,
-                                                             u,
-                                                             matrix,
-                                                             b );*/
-}
-
-} // namespace TNL
-
-#endif /* advectionPROBLEM_IMPL_H_ */
diff --git a/examples/advection/advectionRhs.h b/examples/advection/advectionRhs.h
deleted file mode 100644
index 1ddb255a09906deece99fbf31df54659f3740a92..0000000000000000000000000000000000000000
--- a/examples/advection/advectionRhs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <TNL/Functions/Domain.h>
-
-namespace TNL {
-
-template< typename Mesh, typename Real >class advectionRhs
-  : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > 
-{
-   public:
-
-      typedef Mesh MeshType;
-      typedef Real RealType;
-
-      bool setup( const Config::ParameterContainer& parameters,
-                  const String& 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;
-      }
-};
-
-} // namespace TNL
-
diff --git a/examples/advection/tnl-run-advection b/examples/advection/tnl-run-advection
deleted file mode 100644
index 2946d5bbf414ca5721c62bb6aedce23fe420e5c1..0000000000000000000000000000000000000000
--- a/examples/advection/tnl-run-advection
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/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 exp \
-	      --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
deleted file mode 100644
index e38101223bd7628a15bdc658e7bd2831590896a1..0000000000000000000000000000000000000000
--- a/examples/advection/tnl-run-advection1
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/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 exp_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
deleted file mode 100644
index 78ae8349db048aec97c8a079055569a08091759e..0000000000000000000000000000000000000000
--- a/examples/advection/tnl-run-advectionrot1
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/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 exp_square \
-	      --advection-speedX 2.0 \
-	      --advection-speedY 2.0 \
-              --move rotation \
-
-tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/heat-equation/CMakeLists.txt b/examples/heat-equation/CMakeLists.txt
old mode 100755
new mode 100644
index 4b5bc34dba38e819d901cf46f311283c645d9c1a..9614bb21a6c453f80c6222b51899b7b33e74150d
--- a/examples/heat-equation/CMakeLists.txt
+++ b/examples/heat-equation/CMakeLists.txt
@@ -12,8 +12,9 @@ IF( BUILD_CUDA )
 ELSE(  BUILD_CUDA )               
    ADD_EXECUTABLE(tnl-heat-equation${debugExt} tnl-heat-equation.cpp)     
    ADD_EXECUTABLE(tnl-heat-equation-eoc-test${debugExt} tnl-heat-equation-eoc.cpp)   
-   target_link_libraries (tnl-heat-equation${debugExt} tnl${debugExt}-${tnlVersion} )
+   target_link_libraries (tnl-heat-equation${debugExt} tnl${debugExt}-${tnlVersion})
    target_link_libraries (tnl-heat-equation-eoc-test${debugExt} tnl${debugExt}-${tnlVersion} )
+   TARGET_COMPILE_DEFINITIONS( tnl-heat-equation${debugExt} PUBLIC ${MIC_CXX_FLAGS} )
 ENDIF( BUILD_CUDA )
 
 
diff --git a/examples/heat-equation/HeatEquationBuildConfigTag.h b/examples/heat-equation/HeatEquationBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..8579b7f473c6ab1a3472aaa8a11913758390a15a
--- /dev/null
+++ b/examples/heat-equation/HeatEquationBuildConfigTag.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+                          HeatEquationBuildConfigTag.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Solvers/BuildConfigTags.h>
+
+namespace TNL {
+namespace Solvers {
+   
+class HeatEquationBuildConfig
+{
+   public:
+
+      static void print() { std::cerr << "HeatEquationBuildConfig" << std::endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct ConfigTagReal< HeatEquationBuildConfig, float > { enum { enabled = false }; };
+template<> struct ConfigTagReal< HeatEquationBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct ConfigTagIndex< HeatEquationBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct ConfigTagIndex< HeatEquationBuildConfig, long int >{ enum { enabled = false }; };
+
+/****
+ * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+template< int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< HeatEquationBuildConfig, Meshes::Grid< Dimension, Real, Device, Index > >
+      { enum { enabled = ConfigTagDimension< HeatEquationBuildConfig, Dimension >::enabled  &&
+                         ConfigTagReal< HeatEquationBuildConfig, Real >::enabled &&
+                         ConfigTagDevice< HeatEquationBuildConfig, Device >::enabled &&
+                         ConfigTagIndex< HeatEquationBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretization  here.
+ */
+template<> struct ConfigTagTimeDiscretisation< HeatEquationBuildConfig, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct ConfigTagTimeDiscretisation< HeatEquationBuildConfig, SemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+template<> struct ConfigTagTimeDiscretisation< HeatEquationBuildConfig, ImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct ConfigTagExplicitSolver< HeatEquationBuildConfig, ExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+} // namespace Solvers
+} // namespace TNL
diff --git a/examples/heat-equation/tnl-heat-equation-eoc.h b/examples/heat-equation/tnl-heat-equation-eoc.h
index 276763247c2434357e26503635368d30150c2af8..f9876fb9adf66479282f1223bd48fb10da759ae7 100644
--- a/examples/heat-equation/tnl-heat-equation-eoc.h
+++ b/examples/heat-equation/tnl-heat-equation-eoc.h
@@ -53,17 +53,17 @@ class heatEquationSetter
    typedef Device DeviceType;
    typedef Index IndexType;
 
-   typedef Containers::StaticVector< MeshType::meshDimensions, Real > Vertex;
+   typedef Containers::StaticVector< MeshType::getMeshDimension(), Real > Point;
 
    static bool run( const Config::ParameterContainer& parameters )
    {
-      enum { Dimensions = MeshType::meshDimensions };
+      enum { Dimension = MeshType::getMeshDimension() };
       typedef Operators::LinearDiffusion< MeshType, Real, Index > ApproximateOperator;
-      typedef Operators::ExactLinearDiffusion< Dimensions > ExactOperator;
-      typedef Functions::TestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
+      typedef Operators::ExactLinearDiffusion< Dimension > ExactOperator;
+      typedef Functions::TestFunction< MeshType::getMeshDimension(), Real, Device > TestFunction;
       typedef HeatEquationEocRhs< ExactOperator, TestFunction > RightHandSide;
-      typedef Containers::StaticVector < MeshType::meshDimensions, Real > Vertex;
-      typedef Operators::DirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
+      typedef Containers::StaticVector < MeshType::getMeshDimension(), Real > Point;
+      typedef Operators::DirichletBoundaryConditions< MeshType, TestFunction, Dimension, Real, Index > BoundaryConditions;
       typedef HeatEquationEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
       SolverStarter solverStarter;
       return solverStarter.template run< Solver >( parameters );
diff --git a/examples/heat-equation/tnl-heat-equation.h b/examples/heat-equation/tnl-heat-equation.h
index 43a42da6689b68747005a9378add270c60a522d7..1a0041f93e3f6edeb73b8bfe9d632ed9538f9f41 100644
--- a/examples/heat-equation/tnl-heat-equation.h
+++ b/examples/heat-equation/tnl-heat-equation.h
@@ -21,12 +21,14 @@
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Problems/HeatEquationProblem.h>
 #include <TNL/Meshes/Grid.h>
+#include "HeatEquationBuildConfigTag.h"
 
 using namespace TNL;
 using namespace TNL::Problems;
 
 //typedef tnlDefaultBuildMeshConfig BuildConfig;
 typedef Solvers::FastBuildConfig BuildConfig;
+//typedef Solvers::HeatEquationBuildConfig BuildConfig;
 
 template< typename MeshConfig >
 class heatEquationConfig
@@ -46,7 +48,7 @@ class heatEquationConfig
          config.addEntry< String >( "boundary-conditions-file", "File with the values of the boundary conditions.", "boundary.tnl" );
          config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
          config.addEntry< double >( "right-hand-side-constant", "This sets a constant value for the right-hand side.", 0.0 );
-         //config.addEntry< String >( "initial-condition", "File with the initial condition.", "initial.tnl");
+         config.addEntry< String >( "initial-condition", "File with the initial condition.", "initial.tnl");
       };
 };
 
@@ -64,19 +66,16 @@ class heatEquationSetter
    typedef Device DeviceType;
    typedef Index IndexType;
 
-   typedef Containers::StaticVector< MeshType::meshDimensions, Real > Vertex;
-
    static bool run( const Config::ParameterContainer& parameters )
    {
-      enum { Dimensions = MeshType::meshDimensions };
+      enum { Dimension = MeshType::getMeshDimension() };
       typedef Operators::LinearDiffusion< MeshType, Real, Index > ApproximateOperator;
-      typedef Functions::Analytic::Constant< Dimensions, Real > RightHandSide;
-      typedef Containers::StaticVector < MeshType::meshDimensions, Real > Vertex;
+      typedef Functions::Analytic::Constant< Dimension, Real > RightHandSide;
 
       String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
       if( parameters.checkParameter( "boundary-conditions-constant" ) )
       {
-         typedef Functions::Analytic::Constant< Dimensions, Real > Constant;
+         typedef Functions::Analytic::Constant< Dimension, Real > Constant;
          if( boundaryConditionsType == "dirichlet" )
          {
             typedef Operators::DirichletBoundaryConditions< MeshType, Constant > BoundaryConditions;
diff --git a/examples/heat-equation/tnl-run-heat-equation-eoc-test b/examples/heat-equation/tnl-run-heat-equation-eoc-test
index fb39336e07eec7bbcd288cbdf3be2942404f3232..014d13ebab35272cbef5aeafbeb2a692bd368daa 100644
--- a/examples/heat-equation/tnl-run-heat-equation-eoc-test
+++ b/examples/heat-equation/tnl-run-heat-equation-eoc-test
@@ -1,6 +1,7 @@
 #!/bin/bash
 
 device="host"
+threadsNumbers="1 2 4 6"
 dimensions="1D 2D 3D"
 #dimensions="1D"
 sizes1D="16 32 64 128 256 512"
@@ -84,6 +85,7 @@ solve()
 {
    timeDiscretisation=$1
    discreteSolver=$2
+   threadsNumber=$3
    ${solverName} --device ${device} \
                  --mesh mesh.tnl \
                  --initial-condition exact-u-00000.tnl \
@@ -113,7 +115,10 @@ solve()
                  --sigma ${sigma} \
                  --time-dependence ${timeDependence} \
                  --snapshot-period ${snapshotPeriod} \
-                 --final-time ${finalTime}
+                 --final-time ${finalTime} \
+                 --refresh-rate 50 \
+                 --openmp-enabled true \
+                 --openmp-max-threads ${threadsNumber}
 }
                
 computeError()
@@ -128,77 +133,84 @@ computeError()
 
 runTest()
 {
-   for testFunction in ${testFunctions};
+   for threadsNumber in ${threadsNumbers};
    do
-      mkdir -p ${testFunction}
-      cd ${testFunction}
-      setupTestFunction ${testFunction}
-      
-      for dim in ${dimensions};
-      do
-         mkdir -p $dim
-         cd ${dim}
-         if test $dim = 1D;
-         then 
-            sizes=$sizes1D
-         fi
-         if test $dim = 2D;
-         then 
-            sizes=$sizes2D
-         fi
-         if test $dim = 3D;
-         then 
-            sizes=$sizes3D
-         fi
-         
-         lastSize=""
-         for size in $sizes;
-         do
-            mkdir -p $size
-            cd $size
-            echo ""
-            echo ""
-            echo ""
-            if test ! -f computation-done;
-            then
-               touch computation-in-progress
-               echo "========================================================================="
-               echo "===                   SETTING UP THE GRID                             ==="
-               echo "========================================================================="
-               setupGrid $dim $size 
-               echo "========================================================================="
-               echo "===                WRITING THE EXACT SOLUTION                         ==="
-               echo "========================================================================="
-               setInitialCondition $testFunction
-               echo "========================================================================="
-               echo "===                   STARTING THE SOLVER                             ==="
-               echo "========================================================================="
-               #solve explicit merson
-               solve semi-implicit gmres
-               mv computation-in-progress computation-done
-            fi            
-            echo "========================================================================="
-            echo "===                   COMPUTING THE ERROR                             ==="
-            echo "========================================================================="
-            computeError
-            echo "========================================================================="
-            echo "===                     COMPUTING THE EOC                             ==="            
-            echo "========================================================================="
-            if test ! x$lastSize = x;
-            then
-               tnl-err2eoc ../$lastSize/errors.txt errors.txt
-            fi
-            echo "========================================================================="
-            echo "===                     COMPUTATION DONE                              ==="            
-            echo "========================================================================="
-            cd ..
-            lastSize=$size
-         done
+      mkdir -p threads-${threadsNumber}
+      cd threads-${threadsNumber}
 
-         cd ..
-      done
-      cd ..
-   done
+        for testFunction in ${testFunctions};
+        do
+           mkdir -p ${testFunction}
+           cd ${testFunction}
+           setupTestFunction ${testFunction}
+
+           for dim in ${dimensions};
+           do
+              mkdir -p $dim
+              cd ${dim}
+              if test $dim = 1D;
+              then 
+                 sizes=$sizes1D
+              fi
+              if test $dim = 2D;
+              then 
+                 sizes=$sizes2D
+              fi
+              if test $dim = 3D;
+              then 
+                 sizes=$sizes3D
+              fi
+
+              lastSize=""
+              for size in $sizes;
+              do
+                 mkdir -p $size
+                 cd $size
+                 echo ""
+                 echo ""
+                 echo ""
+                 if test ! -f computation-done;
+                 then
+                    touch computation-in-progress
+                    echo "========================================================================="
+                    echo "===                   SETTING UP THE GRID                             ==="
+                    echo "========================================================================="
+                    setupGrid $dim $size 
+                    echo "========================================================================="
+                    echo "===                WRITING THE EXACT SOLUTION                         ==="
+                    echo "========================================================================="
+                    setInitialCondition $testFunction
+                    echo "========================================================================="
+                    echo "===                   STARTING THE SOLVER                             ==="
+                    echo "========================================================================="
+                    #solve explicit merson ${threadsNumber}
+                    solve semi-implicit gmres ${threadsNumber}
+                    mv computation-in-progress computation-done
+                 fi            
+                 echo "========================================================================="
+                 echo "===                   COMPUTING THE ERROR                             ==="
+                 echo "========================================================================="
+                 computeError
+                 echo "========================================================================="
+                 echo "===                     COMPUTING THE EOC                             ==="            
+                 echo "========================================================================="
+                 if test ! x$lastSize = x;
+                 then
+                    tnl-err2eoc ../$lastSize/errors.txt errors.txt
+                 fi
+                 echo "========================================================================="
+                 echo "===                     COMPUTATION DONE                              ==="            
+                 echo "========================================================================="
+                 cd ..
+                 lastSize=$size
+              done
+
+              cd ..
+           done
+           cd ..
+        done
+        cd ..
+    done
 }
 
 runTest
diff --git a/examples/inviscid-flow/1d/CMakeLists.txt b/examples/inviscid-flow/1d/CMakeLists.txt
deleted file mode 100644
index 6fe0766eec90a76d7888c56f615122804abf4bcc..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-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/Euler1DPressureGetter.h b/examples/inviscid-flow/1d/Euler1DPressureGetter.h
deleted file mode 100644
index 57f3ff859d517b0f403e376f25c135be9efe96aa..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/Euler1DPressureGetter.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef EulerPressureGetter_H
-#define EulerPressureGetter_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-#include <TNL/Functions/Domain.h>
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class EulerPressureGetter
-: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain >
-{
-   public:
-      
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef Real RealType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      
-      EulerPressureGetter( const MeshFunctionType& rho,
-                           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
-      {
-          if (this->rho[ idx ]==0) return 0; else return ( this->gamma - 1.0 ) * ( this->energy[ idx ] - 0.5 * this->rhoVel[ idx ] * this->rhoVel[ idx ] / this->rho[ idx ]);
-          //return ( this->gamma - 1.0 ) * this->energy[ idx ] * this->rho[ idx ];
-
-      }
-
-      
-   protected:
-      
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVel;
-      
-      const MeshFunctionType& energy;
-
-      RealType gamma;
-
-};
-
-} //namespace TNL
-
-#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/1d/Euler1DVelGetter.h b/examples/inviscid-flow/1d/Euler1DVelGetter.h
deleted file mode 100644
index f32bf8a3a09448ab2b7b8b82544aa36dffe4abc4..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/Euler1DVelGetter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef EulerVelGetter_H
-#define EulerVelGetter_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class EulerVelGetter
-: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain >
-{
-   public:
-      
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef Real RealType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String 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
-      {
-          if (this->rho[ idx ]==0) return 0; else return this->rhoVel[ idx ] / this->rho[ idx ];
-      }
-
-      
-   protected:
-      
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVel;
-
-};
-
-} // namespace TNL
-
-#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichs1D.h b/examples/inviscid-flow/1d/LaxFridrichs1D.h
deleted file mode 100644
index e24dee38825ba64a4304c4b2fbbaff6a881ae618..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichs1D.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef LaxFridrichs1D_H
-#define LaxFridrichs1D_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-#include "LaxFridrichsContinuity.h"
-#include "LaxFridrichsMomentum.h"
-#include "LaxFridrichsEnergy.h"
-#include "Euler1DVelGetter.h"
-#include "Euler1DPressureGetter.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class LaxFridrichs1D
-{
-   public:
-      typedef Real RealType;
-      typedef typename Mesh::DeviceType DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< 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;
-   
-};
-
-} // namespace TNL
-
-#endif	/* LaxFridrichs1D_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity.h
deleted file mode 100644
index f3d1d31cf9dea7590afc9e4a6553e9f7ec87f97b..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef LaxFridrichsContinuity_H
-#define LaxFridrichsContinuity_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind( 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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind( 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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind( 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;
-};
-
-} // namespace TNL
-
-#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
deleted file mode 100644
index dd13d36428bff4eb2a2713964d7c56b9ddf41d7c..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h
+++ /dev/null
@@ -1,347 +0,0 @@
-#ifndef LaxFridrichsContinuity_IMPL_H
-#define LaxFridrichsContinuity_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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[ east ] * this->velocity[ east ] - u[ west ] * this->velocity[ west ] );
-	  /*(0.5) * ( u[ west ]  + u[ east ] ) 
-          - 0.5 * hxInverse * this->tau * ( u[ east ] * this->velocity[ east ] - u[ west ] * this->velocity[ west ] );*/
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsContinuity< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} // namespace TNL
-
-#endif	/* LaxFridrichsContinuityIMPL_H */
-
diff --git a/examples/inviscid-flow/1d/LaxFridrichsEnergy.h b/examples/inviscid-flow/1d/LaxFridrichsEnergy.h
deleted file mode 100644
index bc351758d96611566e3512447ae11a72360db3b4..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsEnergy.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef LaxFridrichsEnergy_H
-#define LaxFridrichsEnergy_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-	  this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-} // namespace TNL
-
-#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
deleted file mode 100644
index ebc7fb825f945478d3c414174fee93af36268d14..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h
+++ /dev/null
@@ -1,352 +0,0 @@
-#ifndef LaxFridrichsEnergy_IMPL_H
-#define LaxFridrichsEnergy_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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[ east ] + this->pressure[ east ] ) * velocity[ east ]  
-          -( u[ west ] + this->pressure[ west ] ) * velocity[ west ] );
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsEnergyIMPL_H */
-
diff --git a/examples/inviscid-flow/1d/LaxFridrichsMomentum.h b/examples/inviscid-flow/1d/LaxFridrichsMomentum.h
deleted file mode 100644
index 3f6748d89c899f2cc38b476ba6be738c016d30be..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsMomentum.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef LaxFridrichsMomentum_H
-#define LaxFridrichsMomentum_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-	  this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocity;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocity(MeshFunctionType& velocity)
-      {
-          this->velocity.bind(velocity);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-} // namespace TNL
-
-
-#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
deleted file mode 100644
index ebfe4073242260eb950e74d6614d1728f7a8fd77..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef LaxFridrichsMomentum_IMPL_H
-#define LaxFridrichsMomentum_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentum< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentum< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentum< Meshes::Grid< 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[ east ] * this -> velocity[ east ] + this -> pressure [ east ] ) 
-          -( u[ west ] * this -> velocity[ west ] + this -> pressure [ west ] ));
-	  /*(0.5) * ( u[ west ] + u[ east ] ) 
-          - 0.5 * hxInverse * this->tau *
-          (( u[ east ] * this -> velocity[ east ] + this -> pressure [ east ] ) 
-          -( u[ west ] * this -> velocity[ west ] + this -> pressure [ west ] ));*/
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentum< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentum< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentum< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentum< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentum< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentum< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentum< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} // namespace TNL
-
-#endif	/* LaxFridrichsMomentumIMPL_H */
-
diff --git a/examples/inviscid-flow/1d/eulerBuildConfigTag.h b/examples/inviscid-flow/1d/eulerBuildConfigTag.h
deleted file mode 100644
index abede16343a81cde5e75386f8b2e15117fd6672d..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/eulerBuildConfigTag.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef eulerBUILDCONFIGTAG_H_
-#define eulerBUILDCONFIGTAG_H_
-
-#include <TNL/Solvers/BuildConfigTags.h>
-
-namespace TNL {
-
-class eulerBuildConfigTag{};
-
-namespace Solvers {
-
-/****
- * Turn off support for float and long double.
- */
-template<> struct ConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; };
-template<> struct ConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; };
-
-/****
- * Turn off support for short int and long int indexing.
- */
-template<> struct ConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; };
-template<> struct ConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; };
-
-template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 1 ) }; };
-
-/****
- * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
- */
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< eulerBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled  &&
-                         ConfigTagReal< eulerBuildConfigTag, Real >::enabled &&
-                         ConfigTagDevice< eulerBuildConfigTag, Device >::enabled &&
-                         ConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; };
-
-/****
- * Please, chose your preferred time discretisation  here.
- */
-template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
-template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
-template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
-
-/****
- * Only the Runge-Kutta-Merson solver is enabled by default.
- */
-template<> struct ConfigTagExplicitSolver< eulerBuildConfigTag, ExplicitEulerSolverTag >{ enum { enabled = true }; };
-
-} // namespace Solvers
-} // namespace TNL
-
-#endif /* eulerBUILDCONFIGTAG_H_ */
diff --git a/examples/inviscid-flow/1d/eulerProblem_impl.h b/examples/inviscid-flow/1d/eulerProblem_impl.h
deleted file mode 100644
index 82e89903d4b707906e14edfeca52cdb8c0ec2d70..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/eulerProblem_impl.h
+++ /dev/null
@@ -1,343 +0,0 @@
-#ifndef eulerPROBLEM_IMPL_H_
-#define eulerPROBLEM_IMPL_H_
-
-#include <TNL/FileName.h>
-#include <TNL/Matrices/MatrixSetter.h>
-#include <TNL/Solvers/PDE/ExplicitUpdater.h>
-#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
-#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
-#include "LaxFridrichsContinuity.h"
-#include "LaxFridrichsMomentum.h"
-#include "LaxFridrichsEnergy.h"
-#include "Euler1DVelGetter.h"
-#include "Euler1DPressureGetter.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getTypeStatic()
-{
-   return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getPrologHeader() const
-{
-   return String( "euler" );
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-writeProlog( Logger& logger, const Config::ParameterContainer& 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 MeshPointer& meshPointer,
-       const Config::ParameterContainer& parameters,
-       const String& prefix )
-{
-   if( //! this->boundaryConditionsPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ||
-       ! this->rightHandSidePointer->setup( parameters, prefix + "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 MeshPointer& 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 MeshPointer& mesh,
-          DofVectorPointer& dofVector )
-{
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setInitialCondition( const Config::ParameterContainer& parameters,
-                     const MeshPointer& mesh,
-                     DofVectorPointer& dofs,
-                     MeshDependentDataPointer& meshDependentData )
-{
-  std::cout << std::endl << "get conditions from CMD";
-   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 / ( rhoL * (gamma - 1) ) );
-   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 / ( rhoR * (gamma - 1) ) );
-   RealType eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * velR * velR;
-   RealType x0 = parameters.getParameter< RealType >( "riemann-border" );
-   int count = mesh->template getEntitiesCount< Cell >();
-   uRho->bind( mesh, *dofs, 0);
-   uRhoVelocity->bind( mesh, *dofs, count);
-   uEnergy->bind( mesh, *dofs, 2 * count);
-   Containers::Vector < RealType, DeviceType, IndexType > data;
-   data.setSize(2*count);
-   velocity->bind( mesh, data, 0);
-   pressure->bind( mesh, data, count );
-   std::cout << std::endl << "set conditions from CMD"<< std::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;
-         };
-   /*
-   const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
-   if( ! dofs.load( initialConditionFile ) )
-   {
-      std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::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 MeshPointer& mesh,
-                   Matrix& matrix )
-{
-/*   const IndexType dofs = this->getDofs( mesh );
-   typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   CompressedRowsLengthsVectorType rowLengths;
-   if( ! rowLengths.setSize( dofs ) )
-      return false;
-   MatrixSetter< 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 MeshPointer& mesh,
-              DofVectorPointer& dofs,
-              MeshDependentDataPointer& meshDependentData )
-{
-   std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
-   this->bindDofs( mesh, dofs );
-   FileName fileName;
-   fileName.setExtension( "tnl" );
-   fileName.setIndex( step );
-   fileName.setFileNameBase( "rho-" );
-   if( ! uRho->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "rhoVel-" );
-   if( ! uRhoVelocity->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "energy-" );
-   if( ! uEnergy->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocity-" );
-   if( ! velocity->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "pressure-" );
-   if( ! pressure->save( fileName.getFileName() ) )
-      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 MeshPointer& mesh,
-                DofVectorPointer& _u,
-                DofVectorPointer& _fu,
-                MeshDependentDataPointer& meshDependentData )
-{
-    typedef typename MeshType::Cell Cell;
-    int count = mesh->template getEntitiesCount< Cell >();
-	//bind _fu
-    this->fuRho->bind(mesh, _fu, 0);
-    this->fuRhoVelocity->bind(mesh, _fu, count);
-    this->fuEnergy->bind(mesh, _fu, 2 * count);
-
-   //generating Differential operator object
-   SharedPointer< Continuity > lF1DContinuity;
-   SharedPointer< Momentum > lF1DMomentum;
-   SharedPointer< Energy > lF1DEnergy;
-
-   //rho
-   this->bindDofs( mesh, _u );
-   lF1DContinuity->setTau(tau);
-   lF1DContinuity->setVelocity( *velocity);
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity;
-   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF1DContinuity,
-                                                           this->boundaryConditionsPointer,
-                                                           this->rightHandSidePointer,
-                                                           uRho,
-                                                           fuRho );
-
-
-   //rhoVelocity
-   lF1DMomentum->setTau(tau);
-   lF1DMomentum->setVelocity( *velocity);
-   lF1DMomentum->setPressure( *pressure);
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Momentum, BoundaryCondition, RightHandSide > explicitUpdaterMomentum;
-   explicitUpdaterMomentum.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF1DMomentum,
-                                                           this->boundaryConditionsPointer,
-                                                           this->rightHandSidePointer,
-                                                           uRhoVelocity,
-                                                           fuRhoVelocity );
-   
-   //energy
-   lF1DEnergy->setTau(tau);
-   lF1DEnergy->setPressure( *pressure);
-   lF1DEnergy->setVelocity( *velocity);
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
-   explicitUpdaterEnergy.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF1DEnergy,
-                                                           this->boundaryConditionsPointer,
-                                                           this->rightHandSidePointer,
-                                                           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 MeshPointer& mesh,
-                      DofVectorPointer& _u,
-                      Matrix& matrix,
-                      DofVectorPointer& b,
-                      MeshDependentDataPointer& meshDependentData )
-{
-/*   LinearSystemAssembler< Mesh,
-                             MeshFunctionType,
-                             DifferentialOperator,
-                             BoundaryCondition,
-                             RightHandSide,
-                             BackwardTimeDiscretisation,
-                             Matrix,
-                             DofVectorType > systemAssembler;
-
-   MeshFunction< 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 MeshPointer& mesh,
-             DofVectorPointer& dofs,
-             MeshDependentDataPointer& 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;
-   return true;
-}
-
-} // namespace TNL
-
-#endif /* eulerPROBLEM_IMPL_H_ */
diff --git a/examples/inviscid-flow/1d/eulerRhs.h b/examples/inviscid-flow/1d/eulerRhs.h
deleted file mode 100644
index 1b46dc831fe9daa6133ff32ee4bea5faf4eb8d1c..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/eulerRhs.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef eulerRHS_H_
-#define eulerRHS_H_
-
-#include <TNL/Functions/Domain.h>
-
-namespace TNL {
-
-template< typename Mesh, typename Real >class eulerRhs
-  : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > 
- {
-   public:
-
-      typedef Mesh MeshType;
-      typedef Real RealType;
-
-      bool setup( const Config::ParameterContainer& parameters,
-                  const String& 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;
-      }
-};
-
-} //namespace TNL
-
-#endif /* eulerRHS_H_ */
diff --git a/examples/inviscid-flow/1d/tnl-run-euler-1d b/examples/inviscid-flow/1d/tnl-run-euler-1d
deleted file mode 100644
index a57250e6be3910a03a5f8a01b755c39d97cffb47..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/tnl-run-euler-1d
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/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-type mymixed \
-              --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
deleted file mode 100644
index d753d50afcc11a2fccbe04e30410c77e8a5c1f81..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644
index a251372a773e5d7ebe4dae3297f80517802deb84..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerPressureGetter.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef EulerPressureGetter_H
-#define EulerPressureGetter_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-#include <TNL/Functions/Domain.h>
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class EulerPressureGetter
-: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain >
-{
-   public:
-      
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef Real RealType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      
-      EulerPressureGetter( const MeshFunctionType& rho,
-                           const MeshFunctionType& rhoVelX,
-                           const MeshFunctionType& rhoVelY,
-                           const MeshFunctionType& energy,
-                           const RealType& gamma )
-      : rho( rho ), rhoVelX( rhoVelX ), rhoVelY( rhoVelY ), 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
-            {
-         if (this->rho[ idx ]==0) {return 0;} 
-         else return ( this->gamma - 1.0 ) * ( this->energy[ idx ] - 0.5 * this->rho[ idx ] * 
-         ( std::pow(this->rhoVelX[ idx ] / this->rho[ idx ],2) + std::pow(this->rhoVelY[ idx ] / this->rho[ idx ],2) ) );
-//*/       return ( this->gamma - 1.0 ) * ( this->energy[ idx ] * this->rho[ idx ] );
-      }
-
-      
-   protected:
-
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVelX;
-      
-      const MeshFunctionType& rhoVelY;
-
-      const MeshFunctionType& energy;
-
-      RealType gamma;
-
-};
-
-} //namespace TNL
-
-#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelGetter.h b/examples/inviscid-flow/2d/EulerVelGetter.h
deleted file mode 100644
index 31106299ba6e793773ea67b45eaab927890d1e5b..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelGetter.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef EulerVelGetter_H
-#define EulerVelGetter_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class EulerVelGetter
-: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain >
-{
-   public:
-      
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef Real RealType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      
-      EulerVelGetter( const MeshFunctionType& rho,
-                      const MeshFunctionType& rhoVelX,
-                      const MeshFunctionType& rhoVelY)
-      : rho( rho ), rhoVelX( rhoVelX ), rhoVelY( rhoVelY )
-      {}
-
-      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
-      {
-         if (this->rho[ idx ]==0) return 0; else return std::sqrt( std::pow( this->rhoVelX[ idx ] / this->rho[ idx ], 2) + std::pow( this->rhoVelY[ idx ] / this->rho[ idx ], 2) ) ;
-      }
-
-      
-   protected:
-      
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVelX;
-
-      const MeshFunctionType& rhoVelY;
-
-};
-
-} // namespace TNL
-
-#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichs2D.h b/examples/inviscid-flow/2d/LaxFridrichs2D.h
deleted file mode 100644
index 74c17d7fadfddbabfd581b8f62db839146ff4ad9..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichs2D.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef LaxFridrichs2D_H
-#define LaxFridrichs2D_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-#include "LaxFridrichsContinuity.h"
-#include "LaxFridrichsEnergy.h"
-#include "LaxFridrichsMomentumX.h"
-#include "LaxFridrichsMomentumY.h"
-#include "EulerPressureGetter.h"
-#include "Euler2DVelXGetter.h"
-#include "EulerVelGetter.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class LaxFridrichs2D
-{
-   public:
-      typedef Real RealType;
-      typedef typename Mesh::DeviceType DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< 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 EulerVelGetter< Mesh, Real, Index > Velocity;
-      typedef EulerPressureGetter< Mesh, Real, Index > Pressure;
-   
-};
-
-} //namespace TNL
-
-#endif	/* LaxFridrichs2D_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h b/examples/inviscid-flow/2d/LaxFridrichsContinuity.h
deleted file mode 100644
index 3b125b7f619c13bf5194ca0a8739d3dbf130e774..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h
+++ /dev/null
@@ -1,204 +0,0 @@
-#ifndef LaxFridrichsContinuity_H
-#define LaxFridrichsContinuity_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(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;
-};
-
-
-} //namespace TNL
-
-#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
deleted file mode 100644
index 539e574c96d6171a40407e58803d5c81e1f50acd..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h	
+++ /dev/null
@@ -1,349 +0,0 @@
-#ifndef LaxFridrichsContinuity_IMPL_H
-#define LaxFridrichsContinuity_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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 0;/*( 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ( u[ east ] * this->velocityX[ east ] - u[ west ] * this->velocityX[ west ] )
-          - 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
-LaxFridrichsContinuity< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsContinuity< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsContinuity< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsContinuityIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/LaxFridrichsEnergy.h b/examples/inviscid-flow/2d/LaxFridrichsEnergy.h
deleted file mode 100644
index d531664fd6b00446c7a72d7f189f3a192c57655c..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsEnergy.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef LaxFridrichsEnergy_H
-#define LaxFridrichsEnergy_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-} //namespace TNL
-
-
-#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
deleted file mode 100644
index e52cfe4015e232db2df6048ec45150a945aaac5e..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h
+++ /dev/null
@@ -1,350 +0,0 @@
-#ifndef LaxFridrichsEnergy_IMPL_H
-#define LaxFridrichsEnergy_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ((( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] )
-			      -(( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] ))
-          - 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsEnergyIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h
deleted file mode 100644
index b4630ec39e336bd94e814120917e4f34dce08d29..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef LaxFridrichsMomentumX_H
-#define LaxFridrichsMomentumX_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-
-} // namespace TNL
-
-#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
deleted file mode 100644
index ed456a592726d97d301c0763313d68f92eafedc2..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef LaxFridrichsMomentumX_IMPL_H
-#define LaxFridrichsMomentumX_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] ))
-          - 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsMomentumXIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h
deleted file mode 100644
index 2799f2f2bc5e40beb24238bc4ba76ddb0555411a..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifndef LaxFridrichsMomentumY_H
-#define LaxFridrichsMomentumY_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-} // namespace TNL
-
-#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
deleted file mode 100644
index 1689b740ea0c1dc6f1697663a33819c5355d2369..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef LaxFridrichsMomentumY_IMPL_H
-#define LaxFridrichsMomentumY_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * (( 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsMomentumYIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/euler-cuda.cu b/examples/inviscid-flow/2d/euler-cuda.cu
deleted file mode 100644
index 4d76005cb1f70724be978ff0fa6fec63c4a8a76f..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/euler-cuda.cu
+++ /dev/null
@@ -1 +0,0 @@
-#include "euler.h"
diff --git a/examples/inviscid-flow/2d/euler.cpp b/examples/inviscid-flow/2d/euler.cpp
deleted file mode 100644
index 4d76005cb1f70724be978ff0fa6fec63c4a8a76f..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/euler.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "euler.h"
diff --git a/examples/inviscid-flow/2d/euler.h b/examples/inviscid-flow/2d/euler.h
deleted file mode 100644
index ef1da7735ca928a1f2acb9ce8dd2fb5d3ede40fb..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/euler.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <TNL/tnlConfig.h>
-#include <TNL/Solvers/Solver.h>
-#include <TNL/Solvers/BuildConfigTags.h>
-#include <TNL/Operators/DirichletBoundaryConditions.h>
-#include <TNL/Operators/NeumannBoundaryConditions.h>
-#include <TNL/Functions/Analytic/Constant.h>
-#include "eulerProblem.h"
-#include "LaxFridrichs2D.h"
-#include "eulerRhs.h"
-#include "eulerBuildConfigTag.h"
-#include "MyMixedBoundaryConditions.h"
-#include "MyNeumannBoundaryConditions.h"
-
-using namespace TNL;
-
-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( Config::ConfigDescription & config )
-      {
-         config.addDelimiter( "euler2D settings:" );
-         config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
-            config.addEntryEnum< String >( "dirichlet" );
-            config.addEntryEnum< String >( "neumann" );
-            config.addEntryEnum< String >( "mymixed" );
-            config.addEntryEnum< String >( "myneumann" );
-         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
-         config.addEntry< double >( "NW-density", "This sets a value of northwest density." );
-         config.addEntry< double >( "NW-velocityX", "This sets a value of northwest x velocity." );
-         config.addEntry< double >( "NW-velocityY", "This sets a value of northwest y velocity." );
-         config.addEntry< double >( "NW-pressure", "This sets a value of northwest pressure." );
-         config.addEntry< double >( "SW-density", "This sets a value of southwest density." );
-         config.addEntry< double >( "SW-velocityX", "This sets a value of southwest x velocity." );
-         config.addEntry< double >( "SW-velocityY", "This sets a value of southwest y velocity." );
-         config.addEntry< double >( "SW-pressure", "This sets a value of southwest pressure." );
-         config.addEntry< double >( "riemann-border", "This sets a position of discontinuity cross." );
-         config.addEntry< double >( "NE-density", "This sets a value of northeast density." );
-         config.addEntry< double >( "NE-velocityX", "This sets a value of northeast x velocity." );
-         config.addEntry< double >( "NE-velocityY", "This sets a value of northeast y velocity." );
-         config.addEntry< double >( "NE-pressure", "This sets a value of northeast pressure." );
-         config.addEntry< double >( "SE-density", "This sets a value of southeast density." );
-         config.addEntry< double >( "SE-velocityX", "This sets a value of southeast x velocity." );
-         config.addEntry< double >( "SE-velocityY", "This sets a value of southeast y velocity." );
-         config.addEntry< double >( "SE-pressure", "This sets a value of southeast 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 Config::ParameterContainer & parameters )
-      {
-std::cout <<"run";
-          enum { Dimensions = MeshType::getMeshDimensions() };
-          typedef LaxFridrichs2D< MeshType, Real, Index > ApproximateOperator;
-          typedef eulerRhs< MeshType, Real > RightHandSide;
-          typedef Containers::StaticVector < 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 Vector.
-          */
-          String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
-          if( parameters.checkParameter( "boundary-conditions-constant" ) )
-          {
-             typedef Functions::Analytic::Constant< Dimensions, Real > Constant;
-             if( boundaryConditionsType == "dirichlet" )
-             {
-                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-                typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-                SolverStarter solverStarter;
-                return solverStarter.template run< Problem >( parameters );
-             }
-             typedef Operators::NeumannBoundaryConditions< MeshType, Constant, Real, Index > BoundaryConditions;
-             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          typedef Functions::MeshFunction< MeshType > MeshFunction;
-          if( boundaryConditionsType == "dirichlet" )
-          {
-             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "mymixed" )
-          {
-             typedef Operators::MyMixedBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "myneumann" )
-          {
-             typedef Operators::MyNeumannBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
-             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-          if( boundaryConditionsType == "neumann" )
-          {
-             typedef Operators::NeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
-             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-             SolverStarter solverStarter;
-             return solverStarter.template run< Problem >( parameters );
-          }
-    return true;}
-};
-
-int main( int argc, char* argv[] )
-{
-   Solvers::Solver< eulerSetter, eulerConfig, BuildConfig > solver;
-   if( ! solver. run( argc, argv ) )
-      return EXIT_FAILURE;
-   return EXIT_SUCCESS;
-}
diff --git a/examples/inviscid-flow/2d/eulerProblem_impl.h b/examples/inviscid-flow/2d/eulerProblem_impl.h
deleted file mode 100644
index 7c07eafeb0c77288102b159c46be7cc456d68e77..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/eulerProblem_impl.h
+++ /dev/null
@@ -1,451 +0,0 @@
-#include <TNL/FileName.h>
-#include <TNL/Matrices/MatrixSetter.h>
-#include <TNL/Solvers/PDE/ExplicitUpdater.h>
-#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
-#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
-#include "LaxFridrichsContinuity.h"
-#include "LaxFridrichsEnergy.h"
-#include "LaxFridrichsMomentumX.h"
-#include "LaxFridrichsMomentumY.h"
-#include "EulerPressureGetter.h"
-#include "Euler2DVelXGetter.h"
-#include "EulerVelGetter.h"
-#include "MyMixedBoundaryConditions.h"
-#include "MyNeumannBoundaryConditions.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getTypeStatic()
-{
-   return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getPrologHeader() const
-{
-   return String( "euler2D" );
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-writeProlog( Logger& logger, const Config::ParameterContainer& 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 MeshPointer& meshPointer,
-       const Config::ParameterContainer& parameters,
-       const String& prefix )
-{
-   if( //! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ||
-       ! this->rightHandSidePointer->setup( parameters, prefix + "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 MeshPointer& 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 MeshPointer& mesh,
-          DofVectorPointer& dofVector )
-{
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setInitialCondition( const Config::ParameterContainer& parameters,
-                     const MeshPointer& mesh,
-                     DofVectorPointer& dofs,
-                     MeshDependentDataPointer& meshDependentData )
-{
-   typedef typename MeshType::Cell Cell;
-   gamma = parameters.getParameter< RealType >( "gamma" );
-   RealType rhoLu = parameters.getParameter< RealType >( "NW-density" );
-   RealType velLuX = parameters.getParameter< RealType >( "NW-velocityX" );
-   RealType velLuY = parameters.getParameter< RealType >( "NW-velocityY" );
-   RealType preLu = parameters.getParameter< RealType >( "NW-pressure" );
-   //RealType eLu = ( preLu / ( rhoLu * (gamma - 1) ) );
-   RealType eLu = ( preLu / (gamma - 1) ) + 0.5 * rhoLu * ( std::pow(velLuX,2)+std::pow(velLuY,2) );
-   std::cout << rhoLu <<' '<< velLuX<<' '<<velLuY<<' '<<preLu<<' '<<eLu<<' ';  
-   RealType rhoLd = parameters.getParameter< RealType >( "SW-density" );
-   RealType velLdX = parameters.getParameter< RealType >( "SW-velocityX" );
-   RealType velLdY = parameters.getParameter< RealType >( "SW-velocityY" );
-   RealType preLd = parameters.getParameter< RealType >( "SW-pressure" );
-   //RealType eLd = ( preLd / ( rhoLd * (gamma - 1) ) );
-   RealType eLd = ( preLd / (gamma - 1) ) + 0.5 * rhoLd * ( std::pow(velLdX,2)+std::pow(velLdY,2) );
-   std::cout << rhoLd <<' '<< velLdX<<' '<<velLdY<<' '<<preLd<<' '<<eLd<<' '; 
-   RealType rhoRu = parameters.getParameter< RealType >( "NE-density" );
-   RealType velRuX = parameters.getParameter< RealType >( "NE-velocityX" );
-   RealType velRuY = parameters.getParameter< RealType >( "NE-velocityY" );
-   RealType preRu = parameters.getParameter< RealType >( "NE-pressure" );
-   //RealType eRu = ( preRu / ( rhoRu * (gamma - 1) ) );
-   RealType eRu = ( preRu / (gamma - 1) ) + 0.5 * rhoRu * ( std::pow(velRuX,2)+std::pow(velRuY,2) );
-   std::cout << rhoRu <<' '<< velRuX<<' '<<velRuY<<' '<<preRu<<' '<<eRu<<' '; 
-   RealType rhoRd = parameters.getParameter< RealType >( "SE-density" );
-   RealType velRdX = parameters.getParameter< RealType >( "SE-velocityX" );
-   RealType velRdY = parameters.getParameter< RealType >( "SE-velocityY" );
-   RealType preRd = parameters.getParameter< RealType >( "SE-pressure" );
-   //RealType eRd = ( preRd / ( rhoRd * (gamma - 1) ) );
-   RealType eRd = ( preRd / (gamma - 1) ) + 0.5 * rhoRd * ( std::pow(velRdX,2)+std::pow(velRdY,2) );
-   std::cout << rhoRd <<' '<< velRdX<<' '<<velRdY<<' '<<preRd<<' '<<eRd<<' '; 
-   RealType x0 = parameters.getParameter< RealType >( "riemann-border" );
-   int size = mesh->template getEntitiesCount< Cell >();
-   uRho->bind(mesh, dofs, 0);
-   uRhoVelocityX->bind(mesh, dofs, size);
-   uRhoVelocityY->bind(mesh, dofs, 2*size);
-   uEnergy->bind(mesh, dofs, 3*size);
-   Containers::Vector< RealType, DeviceType, IndexType > data;
-   data.setSize(4*size);
-   pressure->bind(mesh, data, 0);
-   velocity->bind(mesh, data, size);
-   velocityX->bind(mesh, data, 2*size);
-   velocityY->bind(mesh, data, 3*size);
-   for(IndexType j = 0; j < std::sqrt(size); j++)   
-      for(IndexType i = 0; i < std::sqrt(size); i++)
-         if ((i <= x0 * std::sqrt(size))&&(j <= x0 * std::sqrt(size)) )
-            {
-               (* uRho)[j*std::sqrt(size)+i] = rhoLd;
-               (* uRhoVelocityX)[j*std::sqrt(size)+i] = rhoLd * velLdX;
-               (* uRhoVelocityY)[j*std::sqrt(size)+i] = rhoLd * velLdY;
-               (* uEnergy)[j*std::sqrt(size)+i] = eLd;
-               (* velocity)[j*std::sqrt(size)+i] = std::sqrt(std::pow(velLdX,2)+std::pow(velLdY,2));
-               (* velocityX)[j*std::sqrt(size)+i] = velLdX;
-               (* velocityY)[j*std::sqrt(size)+i] = velLdY;
-               (* pressure)[j*std::sqrt(size)+i] = preLd;
-            }
-         else
-         if ((i <= x0 * std::sqrt(size))&&(j > x0 * std::sqrt(size)) )
-            {
-               (* uRho)[j*std::sqrt(size)+i] = rhoLu;
-               (* uRhoVelocityX)[j*std::sqrt(size)+i] = rhoLu * velLuX;
-               (* uRhoVelocityY)[j*std::sqrt(size)+i] = rhoLu * velLuY;
-               (* uEnergy)[j*std::sqrt(size)+i] = eLu;
-               (* velocity)[j*std::sqrt(size)+i] = std::sqrt(std::pow(velLuX,2)+std::pow(velLuY,2));
-               (* velocityX)[j*std::sqrt(size)+i] = velLuX;
-               (* velocityY)[j*std::sqrt(size)+i] = velLuY;
-               (* pressure)[j*std::sqrt(size)+i] = preLu;
-            }
-         else
-         if ((i > x0 * std::sqrt(size))&&(j > x0 * std::sqrt(size)) )
-            {
-               (* uRho)[j*std::sqrt(size)+i] = rhoRu;
-               (* uRhoVelocityX)[j*std::sqrt(size)+i] = rhoRu * velRuX;
-               (* uRhoVelocityY)[j*std::sqrt(size)+i] = rhoRu * velRuY;
-               (* uEnergy)[j*std::sqrt(size)+i] = eRu;
-               (* velocity)[j*std::sqrt(size)+i] = std::sqrt(std::pow(velRuX,2)+std::pow(velRuY,2));
-               (* velocityX)[j*std::sqrt(size)+i] = velRuX;
-               (* velocityY)[j*std::sqrt(size)+i] = velRuY;
-               (* pressure)[j*std::sqrt(size)+i] = preRu;
-            }
-         else
-            {
-               (* uRho)[j*std::sqrt(size)+i] = rhoRd;
-               (* uRhoVelocityX)[j*std::sqrt(size)+i] = rhoRd * velRdX;
-               (* uRhoVelocityY)[j*std::sqrt(size)+i] = rhoRd * velRdY;
-               (* uEnergy)[j*std::sqrt(size)+i] = eRd;
-               (* velocity)[j*std::sqrt(size)+i] = std::sqrt(std::pow(velRdX,2)+std::pow(velRdY,2));
-               (* velocityX)[j*std::sqrt(size)+i] = velRdX;
-               (* velocityY)[j*std::sqrt(size)+i] = velRdY;
-               (* pressure)[j*std::sqrt(size)+i] = preRd;
-            };
-   return true; 
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-   template< typename Matrix >
-bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setupLinearSystem( const MeshPointer& mesh,
-                   Matrix& matrix )
-{
-/*   const IndexType dofs = this->getDofs( mesh );
-   typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   CompressedRowsLengthsVectorType rowLengths;
-   if( ! rowLengths.setSize( dofs ) )
-      return false;
-   MatrixSetter< 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 MeshPointer& mesh,
-              DofVectorPointer& dofs,
-              MeshDependentDataPointer& meshDependentData )
-{
-  std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
-   FileName fileName;
-   fileName.setExtension( "tnl" );
-   fileName.setIndex( step );
-   fileName.setFileNameBase( "rho-" );
-   if( ! uRho->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "rhoVelX-" );
-   if( ! uRhoVelocityX->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "rhoVelY-" );
-   if( ! uRhoVelocityY->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "energy-" );
-   if( ! uEnergy->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocityX-" );
-   if( ! velocityX->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocityY-" );
-   if( ! velocityY->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocity-" );
-   if( ! velocity->save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "pressure-" );
-   if( ! pressure->save( fileName.getFileName() ) )
-      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 MeshPointer& mesh,
-                DofVectorPointer& _u,
-                DofVectorPointer& _fu,
-                MeshDependentDataPointer& meshDependentData )
-{
-    typedef typename MeshType::Cell Cell;
-    int count = mesh->template getEntitiesCount< Cell >();
-   //bind MeshFunctionType fu
-   fuRho->bind( mesh, _fu, 0 );
-   fuRhoVelocityX->bind( mesh, _fu, count );
-   fuRhoVelocityY->bind( mesh, _fu, 2*count );
-   fuEnergy->bind( mesh, _fu, 3*count );
-   SharedPointer< Continuity > lF2DContinuity;
-   SharedPointer< MomentumX > lF2DMomentumX;
-   SharedPointer< MomentumY > lF2DMomentumY;
-   SharedPointer< Energy > lF2DEnergy;
-
-   this->bindDofs( mesh, _u );
-   //rho
-   lF2DContinuity->setTau(tau);
-   lF2DContinuity->setVelocityX( *velocityX );
-   lF2DContinuity->setVelocityY( *velocityY );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; 
-   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF2DContinuity,
-                                                           this->boundaryConditionPointer,
-                                                           this->rightHandSidePointer,
-                                                           uRho,
-                                                           fuRho );
-
-   //rhoVelocityX
-   lF2DMomentumX->setTau(tau);
-   lF2DMomentumX->setVelocityX( *velocityX );
-   lF2DMomentumX->setVelocityY( *velocityY );
-   lF2DMomentumX->setPressure( *pressure );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumX, BoundaryCondition, RightHandSide > explicitUpdaterMomentumX; 
-   explicitUpdaterMomentumX.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF2DMomentumX,
-                                                           this->boundaryConditionPointer,
-                                                           this->rightHandSidePointer,
-                                                           uRhoVelocityX,
-                                                           fuRhoVelocityX );
-
-   //rhoVelocityY
-   lF2DMomentumY->setTau(tau);
-   lF2DMomentumY->setVelocityX( *velocityX );
-   lF2DMomentumY->setVelocityY( *velocityY );
-   lF2DMomentumY->setPressure( *pressure );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumY, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY;
-   explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF2DMomentumY,
-                                                           this->boundaryConditionPointer,
-                                                           this->rightHandSidePointer,
-                                                           uRhoVelocityY,
-                                                           fuRhoVelocityY );
-  
-   //energy
-   lF2DEnergy->setTau(tau);
-   lF2DEnergy->setVelocityX( *velocityX ); 
-   lF2DEnergy->setVelocityY( *velocityY ); 
-   lF2DEnergy->setPressure( *pressure );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
-   explicitUpdaterEnergy.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF2DEnergy,
-                                                           this->boundaryConditionPointer,
-                                                           this->rightHandSidePointer,
-                                                           uEnergy,
-                                                           fuEnergy );
-/*
-cout << "rho " << uRho.getData() << endl;
-getchar();
-cout << "rhoVelX " << uRhoVelocityX.getData() << endl;
-getchar();
-cout << "rhoVelY " << uRhoVelocityY.getData() << endl;
-getchar();
-cout << "Energy " << uEnergy.getData() << endl;
-getchar();
-cout << "velocity " << velocity.getData() << endl;
-getchar();
-cout << "velocityX " << velocityX.getData() << endl;
-getchar();
-cout << "velocityY " << velocityY.getData() << endl;
-getchar();
-cout << "pressure " << pressure.getData() << endl;
-getchar();
-*/
-
-
-/*
-   BoundaryConditionsSetter< 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 MeshPointer& mesh,
-                      DofVectorPointer& _u,
-                      Matrix& matrix,
-                      DofVectorPointer& b,
-                      MeshDependentDataPointer& meshDependentData )
-{
-/*   LinearSystemAssembler< Mesh,
-                             MeshFunctionType,
-                             DifferentialOperator,
-                             BoundaryCondition,
-                             RightHandSide,
-                             BackwardTimeDiscretisation,
-                             Matrix,
-                             DofVectorType > systemAssembler;
-
-   MeshFunction< 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 MeshPointer& mesh,
-             DofVectorPointer& dofs,
-             MeshDependentDataPointer& meshDependentData )
-{
-
-   //velocityX
-   this->velocityX->setMesh( mesh );
-   VelocityX velocityXGetter( *uRho, *uRhoVelocityX );
-   *this->velocityX = velocityXGetter;
-
-   //velocityY
-   this->velocityY->setMesh( mesh );
-   VelocityX velocityYGetter( *uRho, *uRhoVelocityY );
-   *this->velocityY = velocityYGetter;
-
-   //velocity
-   this->velocity->setMesh( mesh );
-   Velocity velocityGetter( *uRho, *uRhoVelocityX, *uRhoVelocityY );
-   *this->velocity = velocityGetter;
-
-   //pressure
-   this->pressure->setMesh( mesh );
-   Pressure pressureGetter( *uRho, *uRhoVelocityX, *uRhoVelocityY, *uEnergy, gamma );
-   *this->pressure = pressureGetter;
-
-   return true;
-}
-
-} // namespace TNL
-
diff --git a/examples/inviscid-flow/2d/run-euler b/examples/inviscid-flow/2d/run-euler
deleted file mode 100644
index f68b98a8406dea2f2142526283ec60248551c56d..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/run-euler
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/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/3d/LaxFridrichsContinuity.h b/examples/inviscid-flow/3d/LaxFridrichsContinuity.h
deleted file mode 100644
index f21f12578b6beabc86196183db1eb8eb50bf1541..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsContinuity.h
+++ /dev/null
@@ -1,222 +0,0 @@
-#ifndef LaxFridrichsContinuity_H
-#define LaxFridrichsContinuity_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-
-      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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-
-      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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-
-      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;
-};
-
-
-} //namespace TNL
-
-#include "LaxFridrichsContinuity_impl .h"
-
-#endif	/* LaxFridrichsContinuity_H */
diff --git a/examples/inviscid-flow/3d/LaxFridrichsEnergy_impl.h b/examples/inviscid-flow/3d/LaxFridrichsEnergy_impl.h
deleted file mode 100644
index 9bfe5bc10212371f43f3f0c2913f2cd462da90bd..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsEnergy_impl.h
+++ /dev/null
@@ -1,354 +0,0 @@
-#ifndef LaxFridrichsEnergy_IMPL_H
-#define LaxFridrichsEnergy_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ((( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] )
-			      -(( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] ))
-          - 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsEnergy< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsEnergy< Meshes::Grid< 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
-   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
-   const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
-   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 ((1.0/6.0) / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u[ down ] - 6.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ((( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] )
-			      -(( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * ((( u[ north ] + this->pressure[ north ] ) * this->velocityY[ north ] )
-			      -(( u[ south ] + this->pressure[ south ] ) * this->velocityY[ south ] ))
-          - 0.5 * hzInverse * ((( u[ up ] + this->pressure[ up ] ) * this->velocityY[ up ] )
-			      -(( u[ down ] + this->pressure[ down ] ) * this->velocityY[ down ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsEnergy< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsEnergyIMPL_H */
-
diff --git a/examples/inviscid-flow/3d/LaxFridrichsMomentumX_impl.h b/examples/inviscid-flow/3d/LaxFridrichsMomentumX_impl.h
deleted file mode 100644
index 1fea196fe0794302f8f45b1610d4ba8b699d1f14..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsMomentumX_impl.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef LaxFridrichsMomentumX_IMPL_H
-#define LaxFridrichsMomentumX_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] ))
-          - 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumX< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumX< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumX< Meshes::Grid< 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
-   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
-   const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
-   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 ((1.0/6.0) / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u [ down ] - 6.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] ))
-          - 0.5 * hyInverse * (( u[ north ] * this->velocityY[ north ] )
-			      -( u[ south ] * this->velocityY[ south ] ))
-          - 0.5 * hzInverse * (( u[ up ] * this->velocityZ[ up ] )
-			      -( u[ down ] * this->velocityZ[ down ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentumX< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsMomentumXIMPL_H */
-
diff --git a/examples/inviscid-flow/3d/LaxFridrichsMomentumY.h b/examples/inviscid-flow/3d/LaxFridrichsMomentumY.h
deleted file mode 100644
index 816da05aa24fbda0c06b6c5ef833e8f330b4c7f3..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsMomentumY.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#ifndef LaxFridrichsMomentumY_H
-#define LaxFridrichsMomentumY_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-namespace TNL {
-
-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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
-{
-   public:
-      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
-
-      static String getType();
-      Real tau;
-      MeshFunctionType velocityX;
-      MeshFunctionType velocityY;
-      MeshFunctionType velocityZ;
-      MeshFunctionType pressure;
-
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      void setVelocityX(MeshFunctionType& velocityX)
-      {
-          this->velocityX.bind(velocityX);
-      };
-
-      void setVelocityY(MeshFunctionType& velocityY)
-      {
-          this->velocityY.bind(velocityY);
-      };
-
-      void setVelocityZ(MeshFunctionType& velocityZ)
-      {
-          this->velocityZ.bind(velocityZ);
-      };
-
-      void setPressure(MeshFunctionType& pressure)
-      {
-          this->pressure.bind(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;
-};
-
-} // namespace TNL
-
-#include "LaxFridrichsMomentumY_impl.h"
-
-#endif	/* LaxFridrichsMomentumY_H */
diff --git a/examples/inviscid-flow/3d/LaxFridrichsMomentumY_impl.h b/examples/inviscid-flow/3d/LaxFridrichsMomentumY_impl.h
deleted file mode 100644
index bdec78337a37a27739fe68195c149d8c05e1f24c..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsMomentumY_impl.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef LaxFridrichsMomentumY_IMPL_H
-#define LaxFridrichsMomentumY_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * (( 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< Meshes::Grid< 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< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumY< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumY< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumY< Meshes::Grid< 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
-   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
-   const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
-   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 ((1.0/6.0) / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u[ down ]- 6.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * (( u[ north ] * this->velocityY[ north ] + this->pressure[ north ] )
-			      -( u[ south ] * this->velocityY[ south ] + this->pressure[ south ]))
-          - 0.5 * hzInverse * (( u[ up ] * this->velocityZ[ up ] )
-			      -( u[ down ] * this->velocityZ[ down ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentumY< Meshes::Grid< 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< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsMomentumYIMPL_H */
-
diff --git a/examples/inviscid-flow/3d/LaxFridrichsMomentumZ_impl.h b/examples/inviscid-flow/3d/LaxFridrichsMomentumZ_impl.h
deleted file mode 100644
index 19120336bbd1f82bdb0aa0523f1c35bbc857a428..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/3d/LaxFridrichsMomentumZ_impl.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef LaxFridrichsMomentumZ_IMPL_H
-#define LaxFridrichsMomentumZ_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-LaxFridrichsMomentumZ< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumZ< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumZ< Meshes::Grid< 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
-LaxFridrichsMomentumZ< Meshes::Grid< 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
-LaxFridrichsMomentumZ< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumZ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumZ< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumZ< Meshes::Grid< 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(); 
-
-   //rhoVelZ
-   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.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * (( 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
-LaxFridrichsMomentumZ< Meshes::Grid< 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
-LaxFridrichsMomentumZ< Meshes::Grid< 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 >
-String
-LaxFridrichsMomentumZ< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "LaxFridrichsMomentumZ< " ) +
-          MeshType::getType() + ", " +
-         TNL::getType< Real >() + ", " +
-         TNL::getType< Index >() + " >";
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshFunction, typename MeshEntity >
-__cuda_callable__
-Real
-LaxFridrichsMomentumZ< Meshes::Grid< 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
-   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
-   const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
-   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 (0.25 / this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ east ] * this->velocityX[ east ] )
-			      -( u[ west ] * this->velocityX[ west ] ))
-          - 0.5 * hyInverse * (( u[ north ] * this->velocityX[ north ] )
-			      -( u[ south ] * this->velocityX[ south ] ))
-          - 0.5 * hzInverse * (( u[ up ] * this->velocityY[ up ] + this->pressure[ up ] )
-			      -( u[ down ] * this->velocityY[ down ] + this->pressure[ down ]));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentumZ< Meshes::Grid< 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
-LaxFridrichsMomentumZ< Meshes::Grid< 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 );
-}
-
-} //namespace TNL
-
-#endif	/* LaxFridrichsMomentumZIMPL_H */
-
diff --git a/examples/inviscid-flow/CMakeLists.txt b/examples/inviscid-flow/CMakeLists.txt
index ccad1d243c3f6a201e2e2d02af477c713cc98279..f1a9360c13720f67df4382ff0fd433d8fa63ee16 100644
--- a/examples/inviscid-flow/CMakeLists.txt
+++ b/examples/inviscid-flow/CMakeLists.txt
@@ -1,3 +1,23 @@
-add_subdirectory( 1d )
-add_subdirectory( 2d )
-add_subdirectory( 3d )
+set( tnl_inviscid_flow_HEADERS
+     CompressibleConservativeVariables.h )
+
+set( tnl_inviscid_flow_SOURCES     
+     euler.cpp
+     euler.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(tnl-euler${debugExt} euler.cu)
+   target_link_libraries (tnl-euler${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE(tnl-euler${debugExt} euler.cpp)     
+   target_link_libraries (tnl-euler${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+INSTALL( TARGETS tnl-euler${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES run-euler
+               ${tnl_inviscid_flow_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow )
diff --git a/examples/inviscid-flow/CompressibleConservativeVariables.h b/examples/inviscid-flow/CompressibleConservativeVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3afc845366f8df17b41c5affc5a4e49d5da052a
--- /dev/null
+++ b/examples/inviscid-flow/CompressibleConservativeVariables.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+                          CompressibleConservativeVariables.h  -  description
+                             -------------------
+    begin                : Feb 12, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Functions/MeshFunction.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/SharedPointer.h>
+
+namespace TNL {
+
+template< typename Mesh >
+class CompressibleConservativeVariables
+{
+   public:
+      typedef Mesh MeshType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef typename MeshType::RealType RealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef Functions::MeshFunction< Mesh > MeshFunctionType;
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< MeshType > MeshPointer;      
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef SharedPointer< VelocityFieldType > MomentumFieldPointer;
+      
+      CompressibleConservativeVariables(){};
+      
+      CompressibleConservativeVariables( const MeshPointer& meshPointer )
+      : density( meshPointer ),
+        momentum( meshPointer ),
+        //pressure( meshPointer ),
+        energy( meshPointer ){};
+        
+      void setMesh( const MeshPointer& meshPointer )
+      {
+         this->density->setMesh( meshPointer );
+         this->momentum->setMesh( meshPointer );
+         //this->pressure.setMesh( meshPointer );
+         this->energy->setMesh( meshPointer );
+      }
+      
+      template< typename Vector >
+      void bind( const MeshPointer& meshPointer,
+                 const Vector& data,
+                 IndexType offset = 0 )
+      {
+         IndexType currentOffset( offset );
+         this->density->bind( meshPointer, data, currentOffset );
+         currentOffset += this->density->getDofs( meshPointer );
+         for( IndexType i = 0; i < Dimensions; i++ )
+         {
+            ( *this->momentum )[ i ]->bind( meshPointer, data, currentOffset );
+            currentOffset += ( *this->momentum )[ i ]->getDofs( meshPointer );
+         }
+         this->energy->bind( meshPointer, data, currentOffset );
+      }
+      
+      IndexType getDofs( const MeshPointer& meshPointer ) const
+      {
+         return this->density->getDofs( meshPointer ) + 
+            this->momentum->getDofs( meshPointer ) +
+            this->energy->getDofs( meshPointer );
+      }
+      
+      MeshFunctionPointer& getDensity()
+      {
+         return this->density;
+      }
+
+      const MeshFunctionPointer& getDensity() const
+      {
+         return this->density;
+      }
+      
+      void setDensity( MeshFunctionPointer& density )
+      {
+         this->density = density;
+      }
+      
+      MomentumFieldPointer& getMomentum()
+      {
+         return this->momentum;
+      }
+      
+      const MomentumFieldPointer& getMomentum() const
+      {
+         return this->momentum;
+      }
+      
+      void setMomentum( MomentumFieldPointer& momentum )
+      {
+         this->momentum = momentum;
+      }
+      
+      /*MeshFunctionPointer& getPressure()
+      {
+         return this->pressure;
+      }
+      
+      const MeshFunctionPointer& getPressure() const
+      {
+         return this->pressure;
+      }
+      
+      void setPressure( MeshFunctionPointer& pressure )
+      {
+         this->pressure = pressure;
+      }*/
+      
+      MeshFunctionPointer& getEnergy()
+      {
+         return this->energy;
+      }
+      
+      const MeshFunctionPointer& getEnergy() const
+      {
+         return this->energy;
+      }
+      
+      void setEnergy( MeshFunctionPointer& energy )
+      {
+         this->energy = energy;
+      }
+      
+      void getVelocityField( VelocityFieldType& velocityField )
+      {
+         
+      }
+
+   protected:
+      
+      MeshFunctionPointer density;
+      MomentumFieldPointer momentum;
+      MeshFunctionPointer energy;
+      
+};
+
+} // namespace TN
\ No newline at end of file
diff --git a/examples/inviscid-flow/LaxFridrichs.h b/examples/inviscid-flow/LaxFridrichs.h
new file mode 100644
index 0000000000000000000000000000000000000000..cdf32899f69eb797a6d9a18a52b84c09709867bf
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichs.h
@@ -0,0 +1,141 @@
+/***************************************************************************
+                          LaxFridrichs.h  -  description
+                             -------------------
+    begin                : Feb 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include <TNL/Functions/VectorField.h>
+
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsEnergy.h"
+#include "LaxFridrichsMomentumX.h"
+#include "LaxFridrichsMomentumY.h"
+#include "LaxFridrichsMomentumZ.h"
+
+namespace TNL {
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichs
+{
+   public:
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef typename Mesh::DeviceType DeviceType;
+      typedef Index IndexType;
+      typedef Functions::MeshFunction< Mesh > MeshFunctionType;
+      static const int Dimensions = Mesh::getMeshDimension();
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VectorFieldType;
+ 
+      typedef LaxFridrichsContinuity< Mesh, Real, Index > ContinuityOperatorType;
+      typedef LaxFridrichsMomentumX< Mesh, Real, Index > MomentumXOperatorType;
+      typedef LaxFridrichsMomentumY< Mesh, Real, Index > MomentumYOperatorType;
+      typedef LaxFridrichsMomentumZ< Mesh, Real, Index > MomentumZOperatorType;
+      typedef LaxFridrichsEnergy< Mesh, Real, Index > EnergyOperatorType;
+
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef SharedPointer< VectorFieldType > VectorFieldPointer;
+      typedef SharedPointer< MeshType > MeshPointer;
+      
+      typedef SharedPointer< ContinuityOperatorType > ContinuityOperatorPointer;
+      typedef SharedPointer< MomentumXOperatorType > MomentumXOperatorPointer;
+      typedef SharedPointer< MomentumYOperatorType > MomentumYOperatorPointer;      
+      typedef SharedPointer< MomentumZOperatorType > MomentumZOperatorPointer;      
+      typedef SharedPointer< EnergyOperatorType > EnergyOperatorPointer;
+
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 );
+      }
+      
+      LaxFridrichs()
+         : artificialViscosity( 1.0 ) {}
+      
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" );
+         this->continuityOperatorPointer->setArtificialViscosity( artificialViscosity );
+         this->momentumXOperatorPointer->setArtificialViscosity( artificialViscosity );
+         this->momentumYOperatorPointer->setArtificialViscosity( artificialViscosity );
+         this->momentumZOperatorPointer->setArtificialViscosity( artificialViscosity );
+         this->energyOperatorPointer->setArtificialViscosity( artificialViscosity );
+         
+         return true;
+      }
+      
+      void setTau( const RealType& tau )
+      {
+         this->continuityOperatorPointer->setTau( tau );
+         this->momentumXOperatorPointer->setTau( tau );
+         this->momentumYOperatorPointer->setTau( tau );
+         this->momentumZOperatorPointer->setTau( tau );
+         this->energyOperatorPointer->setTau( tau );
+      }
+      
+      void setPressure( const MeshFunctionPointer& pressure )
+      {
+         this->momentumXOperatorPointer->setPressure( pressure );
+         this->momentumYOperatorPointer->setPressure( pressure );
+         this->momentumZOperatorPointer->setPressure( pressure );
+         this->energyOperatorPointer->setPressure( pressure );
+      }
+      
+      void setVelocity( const VectorFieldPointer& velocity )
+      {
+         this->continuityOperatorPointer->setVelocity( velocity );
+         this->momentumXOperatorPointer->setVelocity( velocity );
+         this->momentumYOperatorPointer->setVelocity( velocity );
+         this->momentumZOperatorPointer->setVelocity( velocity );
+         this->energyOperatorPointer->setVelocity( velocity );
+      }
+      
+      const ContinuityOperatorPointer& getContinuityOperator() const
+      {
+         return this->continuityOperatorPointer;
+      }
+      
+      const MomentumXOperatorPointer& getMomentumXOperator() const
+      {
+         return this->momentumXOperatorPointer;
+      }
+
+      const MomentumYOperatorPointer& getMomentumYOperator() const
+      {
+         return this->momentumYOperatorPointer;
+      }
+      
+      const MomentumZOperatorPointer& getMomentumZOperator() const
+      {
+         return this->momentumZOperatorPointer;
+      }
+      
+      const EnergyOperatorPointer& getEnergyOperator() const
+      {
+         return this->energyOperatorPointer;
+      }
+
+   protected:
+      
+      ContinuityOperatorPointer continuityOperatorPointer;
+      MomentumXOperatorPointer momentumXOperatorPointer;
+      MomentumYOperatorPointer momentumYOperatorPointer;
+      MomentumZOperatorPointer momentumZOperatorPointer;
+      EnergyOperatorPointer energyOperatorPointer;  
+      
+      RealType artificialViscosity;
+};
+
+} //namespace TNL
diff --git a/examples/inviscid-flow/LaxFridrichsContinuity.h b/examples/inviscid-flow/LaxFridrichsContinuity.h
new file mode 100644
index 0000000000000000000000000000000000000000..657230695a5ec9cf84aaa84cd8b82d65e572df90
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsContinuity.h
@@ -0,0 +1,288 @@
+/***************************************************************************
+                          LaxFridrichsContinuity.h  -  description
+                             -------------------
+    begin                : Feb 17, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/SharedPointer.h>
+
+namespace TNL {
+
+   
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsContinuityBase
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef Mesh MeshType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType > VelocityFieldPointer;
+
+      LaxFridrichsContinuityBase()
+       : artificialViscosity( 1.0 ){};
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsContinuity< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+      
+      void setVelocity( const VelocityFieldPointer& velocity )
+      {
+          this->velocity = velocity;
+      };
+      
+      void setArtificialViscosity( const RealType& artificialViscosity )
+      {
+         this->artificialViscosity = artificialViscosity;
+      }
+
+
+      protected:
+         
+         RealType tau;
+         
+         VelocityFieldPointer velocity;
+         
+         RealType artificialViscosity;
+};
+
+   
+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< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsContinuityBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >();
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) 
+               - 0.5 * ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse;
+      }
+
+      /*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< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsContinuityBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+
+         //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  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         
+         return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
+                       - 0.5 * ( ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse
+                               + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse );
+      }
+
+      /*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< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsContinuityBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+
+         //rho
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& velocity_x_west  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_x_east  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         const RealType& velocity_z_up    = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ];
+         const RealType& velocity_z_down  = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ];
+         
+         return 1.0 / 6.0 * this->tau * this->artificialViscosity *
+                ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u[ down ]- 6.0 * u[ center ] ) 
+                - 0.5 * ( ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse
+                        + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse
+                        + ( u[ up ] * velocity_z_up - u[ down ] * velocity_z_down ) * hzInverse );
+         
+      }
+
+      /*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;*/
+};
+
+
+} //namespace TNL
diff --git a/examples/inviscid-flow/LaxFridrichsEnergy.h b/examples/inviscid-flow/LaxFridrichsEnergy.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0af1de01db93d20a7ef800003b15b39228b9718
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsEnergy.h
@@ -0,0 +1,309 @@
+/***************************************************************************
+                          LaxFridrichsEnergy.h  -  description
+                             -------------------
+    begin                : Feb 17, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+
+namespace TNL {
+   
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsEnergyBase
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef Mesh MeshType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef SharedPointer< VelocityFieldType > VelocityFieldPointer;
+      
+      LaxFridrichsEnergyBase()
+       : artificialViscosity( 1.0 ){};
+
+      static String getType()
+      {
+         return String( "LaxFridrichsEnergy< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+      
+      void setVelocity( const VelocityFieldPointer& velocity )
+      {
+          this->velocity = velocity;
+      };
+      
+      void setPressure( const MeshFunctionPointer& pressure )
+      {
+          this->pressure = pressure;
+      };
+      
+      void setArtificialViscosity( const RealType& artificialViscosity )
+      {
+         this->artificialViscosity = artificialViscosity;
+      }      
+
+      protected:
+         
+         RealType tau;
+         
+         VelocityFieldPointer velocity;
+         
+         MeshFunctionPointer pressure;
+         
+         RealType artificialViscosity;
+};
+   
+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< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsEnergyBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& e,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >();
+         const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( e[ west ] - 2.0 * e[ center ]  + e[ east ] ) 
+                - 0.5 * ( ( e[ west ] + pressure_west ) * velocity_x_west  
+                         - ( e[ east ] + pressure_east ) * velocity_x_east ) * hxInverse;
+         
+      }
+
+      /*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< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsEnergyBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& e,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+ 
+         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  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();
+         const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ];
+         const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ];
+         const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];         
+         
+         return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( e[ west ] + e[ east ] + e[ south ] + e[ north ] - 4.0 * e[ center ] ) 
+                - 0.5 * ( ( ( ( e[ west ] + pressure_west ) * velocity_x_west )
+                          -( ( e[ east ] + pressure_east ) * velocity_x_east ) ) * hxInverse
+                        + ( ( ( e[ north ] + pressure_north ) * velocity_y_north )
+                          -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse );
+      }
+
+      /*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< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsEnergyBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& e,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+ 
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& pressure_west  = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east  = this->pressure.template getData< DeviceType >()[ east ];
+         const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ];
+         const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ];
+         const RealType& pressure_up    = this->pressure.template getData< DeviceType >()[ up ];
+         const RealType& pressure_down  = this->pressure.template getData< DeviceType >()[ down ];
+         
+         const RealType& velocity_x_east  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         const RealType& velocity_z_up    = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ];
+         const RealType& velocity_z_down  = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ];         
+         
+         return 1.0 / 6.0 * this->tau * this->artificialViscosity *
+                 ( e[ west ] + e[ east ] + e[ south ] + e[ north ] + e[ up ] + e[ down ] - 6.0 * e[ center ] ) 
+                - 0.5 * ( ( ( ( e[ west ] + pressure_west ) * velocity_x_west )
+                           -( ( e[ east ] + pressure_east ) * velocity_x_east ) ) * hxInverse
+                        + ( ( ( e[ north ] + pressure_north ) * velocity_y_north )
+                           -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse
+                        + ( ( ( e[ up ] + pressure_up ) * velocity_z_up )
+                           -( ( e[ down ] + pressure_down ) * velocity_z_down ) ) * hzInverse );
+      }
+
+      /*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;*/
+};
+
+} //namespace TNL
diff --git a/examples/inviscid-flow/LaxFridrichsMomentumBase.h b/examples/inviscid-flow/LaxFridrichsMomentumBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..67dae9fdf8256cecf032a731dd5d616d715ca0fe
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsMomentumBase.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+                          LaxFridrichsMomentumBase.h  -  description
+                             -------------------
+    begin                : Feb 17, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+namespace TNL {
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsMomentumBase
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef Mesh MeshType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef SharedPointer< VelocityFieldType > VelocityFieldPointer;
+      
+      LaxFridrichsMomentumBase()
+       : artificialViscosity( 1.0 ){};
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+      
+      void setVelocity( const VelocityFieldPointer& velocity )
+      {
+          this->velocity = velocity;
+      };
+      
+      void setPressure( const MeshFunctionPointer& pressure )
+      {
+          this->pressure = pressure;
+      };
+
+      void setArtificialViscosity( const RealType& artificialViscosity )
+      {
+         this->artificialViscosity = artificialViscosity;
+      }
+
+      protected:
+         
+         RealType tau;
+         
+         VelocityFieldPointer velocity;
+         
+         MeshFunctionPointer pressure;
+         
+         RealType artificialViscosity;
+};
+
+} //namespace TNL
diff --git a/examples/inviscid-flow/LaxFridrichsMomentumX.h b/examples/inviscid-flow/LaxFridrichsMomentumX.h
new file mode 100644
index 0000000000000000000000000000000000000000..e054ad6ad261fbf53ef5c2e3a41475be3d992fd8
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsMomentumX.h
@@ -0,0 +1,276 @@
+/***************************************************************************
+                          LaxFridrichsMomentumX.h  -  description
+                             -------------------
+    begin                : Feb 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include "LaxFridrichsMomentumBase.h"
+
+namespace TNL {
+
+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< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumX< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }
+      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >();
+         const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         
+         return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( rho_u[ west ]  + rho_u[ east ]  - 2.0 * rho_u[ center ] ) 
+                - 0.5 * ( ( rho_u[ west ] * velocity_x_west + pressure_west ) 
+                         -( rho_u[ east ] * velocity_x_east + pressure_east ) ) * hxInverse;
+      }
+
+      /*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< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumX< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+
+
+         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  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();
+         
+         const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];         
+         
+         return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] - 4.0 * rho_u[ center ] ) 
+                - 0.5 * ( ( ( rho_u[ west ] * velocity_x_west + pressure_west )
+                          - ( rho_u[ east ] * velocity_x_east + pressure_east ) ) * hxInverse
+                        + ( ( rho_u[ north ] * velocity_y_north )
+                          - ( rho_u[ south ] * velocity_y_south ) ) * hyInverse );
+      }
+
+      /*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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumX< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+ 
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& pressure_west  = this->pressure.template getData< DeviceType >()[ west ];
+         const RealType& pressure_east  = this->pressure.template getData< DeviceType >()[ east ];
+         //const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ];
+         //const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ];
+         //const RealType& pressure_up    = this->pressure.template getData< DeviceType >()[ up ];
+         //const RealType& pressure_down  = this->pressure.template getData< DeviceType >()[ down ];
+         
+         const RealType& velocity_x_east  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         const RealType& velocity_z_up    = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ];
+         const RealType& velocity_z_down  = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ];
+         return 1.0 / 6.0 * this->tau * this->artificialViscosity *
+                   ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] + rho_u[ up ] + rho_u[ down ] - 6.0 * rho_u[ center ] ) 
+                - 0.5 * ( ( ( rho_u[ west ] * velocity_x_west + pressure_west )
+                          - ( rho_u[ east ] * velocity_x_east + pressure_east ) )* hxInverse
+                        + ( ( rho_u[ north ] * velocity_y_north )
+                          - ( rho_u[ south ] * velocity_y_south ) )* hyInverse
+                        + ( ( rho_u[ up ] * velocity_z_up )
+                          - ( rho_u[ down ] * velocity_z_down ) )* hzInverse );
+      }
+
+      /*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;*/
+};
+
+
+} // namespace TNL
+
diff --git a/examples/inviscid-flow/LaxFridrichsMomentumY.h b/examples/inviscid-flow/LaxFridrichsMomentumY.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddf7b022c31831bde9c0c0d877883db63ec697cd
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsMomentumY.h
@@ -0,0 +1,260 @@
+/***************************************************************************
+                          LaxFridrichsMomentumY.h  -  description
+                             -------------------
+    begin                : Feb 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include "LaxFridrichsMomentumBase.h"
+
+namespace TNL {
+
+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< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumY< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }
+      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_v,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         return 0.0;
+      }
+
+      /*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< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumY< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_v,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+
+
+         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  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();
+         
+         const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ];
+         const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ];         
+         const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];         
+         
+         return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] - 4.0 * rho_v[ center ] ) 
+                - 0.5 * ( ( ( rho_v[ west ] * velocity_x_west )
+                           - ( rho_v[ east ] * velocity_x_east ) )* hxInverse
+                        + ( ( rho_v[ north ] * velocity_y_north + pressure_north )
+                          - ( rho_v[ south ] * velocity_y_south + pressure_south ) )* hyInverse );
+      }
+
+      /*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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumY< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_v,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+ 
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ];
+         const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ];
+         const RealType& velocity_x_east  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         const RealType& velocity_z_up    = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ];
+         const RealType& velocity_z_down  = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ];
+         return 1.0 / 6.0 * this->tau * this->artificialViscosity * 
+                   ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] + rho_v[ up ] + rho_v[ down ] - 6.0 * rho_v[ center ] ) 
+                - 0.5 * ( ( ( rho_v[ west ] * velocity_x_west )
+                          - ( rho_v[ east ] * velocity_x_east ) ) * hxInverse
+                        + ( ( rho_v[ north ] * velocity_y_north + pressure_north )
+                          - ( rho_v[ south ] * velocity_y_south + pressure_south ) ) * hyInverse
+                        + ( ( rho_v[ up ] * velocity_z_up )
+                          - ( rho_v[ down ] * velocity_z_down ) ) * hzInverse );
+      }
+
+      /*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;*/
+};
+
+
+} // namespace TNL
+
diff --git a/examples/inviscid-flow/LaxFridrichsMomentumZ.h b/examples/inviscid-flow/LaxFridrichsMomentumZ.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f9213c4d512b79202734f10033d648a0b8cdeeb
--- /dev/null
+++ b/examples/inviscid-flow/LaxFridrichsMomentumZ.h
@@ -0,0 +1,240 @@
+/***************************************************************************
+                          LaxFridrichsMomentumZ.h  -  description
+                             -------------------
+    begin                : Feb 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include "LaxFridrichsMomentumBase.h"
+
+namespace TNL {
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsMomentumZ
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumZ< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumZ< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }
+      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_w,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         return 0.0;
+      }
+
+      /*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 LaxFridrichsMomentumZ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumZ< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_w,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+
+         return 0.0;
+      }
+
+      /*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 LaxFridrichsMomentumZ< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+   : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType;
+      
+      using typename BaseType::RealType;
+      using typename BaseType::IndexType;
+      using typename BaseType::DeviceType;
+      using typename BaseType::CoordinatesType;
+      using typename BaseType::MeshFunctionType;
+      using typename BaseType::MeshFunctionPointer;
+      using typename BaseType::VelocityFieldType;
+      using typename BaseType::VelocityFieldPointer;
+      using BaseType::Dimensions;      
+      
+      static String getType()
+      {
+         return String( "LaxFridrichsMomentumZ< " ) +
+             MeshType::getType() + ", " +
+             TNL::getType< Real >() + ", " +
+             TNL::getType< Index >() + " >"; 
+      }      
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& rho_w,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+ 
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& pressure_up    = this->pressure.template getData< DeviceType >()[ up ];
+         const RealType& pressure_down  = this->pressure.template getData< DeviceType >()[ down ];
+         const RealType& velocity_x_east  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ];
+         const RealType& velocity_x_west  = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ];
+         const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ];
+         const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ];
+         const RealType& velocity_z_up    = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ];
+         const RealType& velocity_z_down  = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ];
+         return 1.0 / 6.0 * this->tau * this->artificialViscosity *
+                    ( rho_w[ west ] + rho_w[ east ] + rho_w[ south ] + rho_w[ north ] + rho_w[ up ] + rho_w[ down ] - 6.0 * rho_w[ center ] ) 
+                -0.5 * ( ( ( rho_w[ west ] * velocity_x_west )
+                         - ( rho_w[ east ] * velocity_x_east ) )* hxInverse
+                       + ( ( rho_w[ north ] * velocity_y_north )
+                         - ( rho_w[ south ] * velocity_y_south ) )* hyInverse
+                       + ( ( rho_w[ up ] * velocity_z_up + pressure_up )
+                         - ( rho_w[ down ] * velocity_z_down + pressure_down ) )* hzInverse );
+      }
+
+      /*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;*/
+};
+
+
+} // namespace TNL
+
diff --git a/examples/inviscid-flow/PhysicalVariablesGetter.h b/examples/inviscid-flow/PhysicalVariablesGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..58fd5df7a5b467a85506aff1c2b28841443269f3
--- /dev/null
+++ b/examples/inviscid-flow/PhysicalVariablesGetter.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+                          CompressibleConservativeVariables.h  -  description
+                             -------------------
+    begin                : Feb 12, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/SharedPointer.h>
+#include <TNL/Functions/MeshFunction.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/Functions/MeshFunctionEvaluator.h>
+#include "CompressibleConservativeVariables.h"
+
+namespace TNL {
+   
+template< typename Mesh >
+class PhysicalVariablesGetter
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef typename MeshType::RealType RealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType;
+      typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer;
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType > VelocityFieldPointer;
+      
+      class VelocityGetter : public Functions::Domain< Dimensions, Functions::MeshDomain >
+      {
+         public:
+            typedef typename MeshType::RealType RealType;
+            
+            VelocityGetter( MeshFunctionPointer density, 
+                            MeshFunctionPointer momentum )
+            : density( density ), momentum( momentum ) {}
+            
+            template< typename EntityType >
+            __cuda_callable__
+            RealType operator()( const EntityType& meshEntity,
+                                        const RealType& time = 0.0 ) const
+            {
+               return momentum.template getData< DeviceType >()( meshEntity ) / 
+                      density.template getData< DeviceType >()( meshEntity );
+            }
+            
+         protected:
+            const MeshFunctionPointer density, momentum;
+      };
+      
+      class PressureGetter : public Functions::Domain< Dimensions, Functions::MeshDomain >
+      {
+         public:
+            typedef typename MeshType::RealType RealType;
+            
+            PressureGetter( MeshFunctionPointer density,
+                            MeshFunctionPointer energy, 
+                            VelocityFieldPointer momentum,
+                            const RealType& gamma )
+            : density( density ), energy( energy ), momentum( momentum ), gamma( gamma ) {}
+            
+            template< typename EntityType >
+            __cuda_callable__
+            RealType operator()( const EntityType& meshEntity,
+                                 const RealType& time = 0.0 ) const
+            {
+               const RealType e = energy.template getData< DeviceType >()( meshEntity );
+               const RealType rho = density.template getData< DeviceType >()( meshEntity );
+               const RealType momentumNorm = momentum.template getData< DeviceType >().getVector( meshEntity ).lpNorm( 2.0 );
+               return ( gamma - 1.0 ) * ( e - 0.5 * momentumNorm * momentumNorm / rho );
+            }
+            
+         protected:
+            const MeshFunctionPointer density, energy;
+            const VelocityFieldPointer momentum;
+            const RealType gamma;
+      };      
+
+      
+      void getVelocity( const ConservativeVariablesPointer& conservativeVariables,
+                        VelocityFieldPointer& velocity )
+      {
+         Functions::MeshFunctionEvaluator< MeshFunctionType, VelocityGetter > evaluator;
+         for( int i = 0; i < Dimensions; i++ )
+         {
+            SharedPointer< VelocityGetter, DeviceType > velocityGetter( conservativeVariables->getDensity(),
+                                                                        ( *conservativeVariables->getMomentum() )[ i ] );
+            evaluator.evaluate( ( *velocity )[ i ], velocityGetter );
+         }
+      }
+      
+      void getPressure( const ConservativeVariablesPointer& conservativeVariables,
+                        const RealType& gamma,
+                        MeshFunctionPointer& pressure )
+      {
+         Functions::MeshFunctionEvaluator< MeshFunctionType, PressureGetter > evaluator;
+         SharedPointer< PressureGetter, DeviceType > pressureGetter( conservativeVariables->getDensity(),
+                                                                     conservativeVariables->getEnergy(),
+                                                                     conservativeVariables->getMomentum(),
+                                                                     gamma );
+         evaluator.evaluate( pressure, pressureGetter );
+      }
+      
+};
+   
+} //namespace TNL
diff --git a/examples/inviscid-flow/RiemannProblemInitialCondition.h b/examples/inviscid-flow/RiemannProblemInitialCondition.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0833efe629687d74c412417c2242b1c8854e401
--- /dev/null
+++ b/examples/inviscid-flow/RiemannProblemInitialCondition.h
@@ -0,0 +1,209 @@
+/***************************************************************************
+                          RiemannProblemInitialCondition.h  -  description
+                             -------------------
+    begin                : Feb 13, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Operators/Analytic/Sign.h>
+#include <TNL/Functions/MeshFunctionEvaluator.h>
+#include <TNL/Operators/Analytic/Sign.h>
+#include "CompressibleConservativeVariables.h"
+
+namespace TNL {
+
+template< typename Mesh >
+class RiemannProblemInitialCondition
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef typename MeshType::RealType RealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef Containers::StaticVector< Dimensions, RealType > PointType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      typedef SharedPointer< MeshFunctionType > MeshFunctionPointer;
+      typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType;
+      
+      RiemannProblemInitialCondition()
+         : discontinuityPlacement( 0.5 ),
+           leftDensity( 1.0 ), rightDensity( 1.0 ),
+           leftVelocity( -2.0 ), rightVelocity( 2.0 ),
+           leftPressure( 0.4 ), rightPressure( 0.4 ),
+           gamma( 1.67 ){}
+
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "discontinuity-placement-0", "x-coordinate of the discontinuity placement.", 0.5 );
+         config.addEntry< double >( prefix + "discontinuity-placement-1", "y-coordinate of the discontinuity placement.", 0.5 );
+         config.addEntry< double >( prefix + "discontinuity-placement-2", "z-coordinate of the discontinuity placement.", 0.5 );
+         config.addEntry< double >( prefix + "left-density", "Density on the left side of the discontinuity.", 1.0 );
+         config.addEntry< double >( prefix + "right-density", "Density on the right side of the discontinuity.", 0.0 );
+         config.addEntry< double >( prefix + "left-velocity-0", "x-coordinate of the velocity on the left side of the discontinuity.", 1.0 );
+         config.addEntry< double >( prefix + "left-velocity-1", "y-coordinate of the velocity on the left side of the discontinuity.", 1.0 );
+         config.addEntry< double >( prefix + "left-velocity-2", "z-coordinate of the velocity on the left side of the discontinuity.", 1.0 );
+         config.addEntry< double >( prefix + "right-velocity-0", "x-coordinate of the velocity on the right side of the discontinuity.", 0.0 );
+         config.addEntry< double >( prefix + "right-velocity-1", "y-coordinate of the velocity on the right side of the discontinuity.", 0.0 );
+         config.addEntry< double >( prefix + "right-velocity-2", "z-coordinate of the velocity on the right side of the discontinuity.", 0.0 );
+         config.addEntry< double >( prefix + "left-pressure", "Pressure on the left side of the discontinuity.", 1.0 );
+         config.addEntry< double >( prefix + "right-pressure", "Pressure on the right side of the discontinuity.", 0.0 );
+         config.addEntry< double >( prefix + "gamma", "Gamma in the ideal gas state equation.", 1.67 );
+      }      
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->discontinuityPlacement.setup( parameters, prefix + "discontinuity-placement-" );
+         this->leftVelocity.setup( parameters, prefix + "left-velocity-" );
+         this->rightVelocity.setup( parameters, prefix + "right-velocity-" );
+         this->leftDensity = parameters.getParameter< double >( prefix + "left-density" );
+         this->rightDensity = parameters.getParameter< double >( prefix + "right-density" );
+         this->leftPressure = parameters.getParameter< double >( prefix + "left-pressure" );
+         this->rightPressure = parameters.getParameter< double >( prefix + "right-pressure" );
+         this->gamma = parameters.getParameter< double >( prefix + "gamma" );
+         return true;
+      };
+      
+      void setDiscontinuityPlacement( const PointType& v )
+      {
+         this->discontinuityPlacement = v;
+      }
+      
+      const PointType& getDiscontinuityPlasement() const
+      {
+         return this->discontinuityPlacement;
+      }
+      
+      void setLeftDensity( const RealType& leftDensity )
+      {
+         this->leftDensity = leftDensity;
+      }
+      
+      const RealType& getLeftDensity() const
+      {
+         return this->leftDensity;
+      }
+      
+      void setRightDensity( const RealType& rightDensity )
+      {
+         this->rightDensity = rightDensity;
+      }
+      
+      const RealType& getRightDensity() const
+      {
+         return this->rightDensity;
+      }
+
+      void setLeftVelocity( const PointType& leftVelocity )
+      {
+         this->leftVelocity = leftVelocity;
+      }
+      
+      const PointType& getLeftVelocity() const
+      {
+         return this->leftVelocity;
+      }
+      
+      void setRightVelocity( const RealType& rightVelocity )
+      {
+         this->rightVelocity = rightVelocity;
+      }
+      
+      const PointType& getRightVelocity() const
+      {
+         return this->rightVelocity;
+      }
+
+      void setLeftPressure( const RealType& leftPressure )
+      {
+         this->leftPressure = leftPressure;
+      }
+      
+      const RealType& getLeftPressure() const
+      {
+         return this->leftPressure;
+      }
+      
+      void setRightPressure( const RealType& rightPressure )
+      {
+         this->rightPressure = rightPressure;
+      }
+      
+      const RealType& getRightPressure() const
+      {
+         return this->rightPressure;
+      }
+      
+      void setInitialCondition( CompressibleConservativeVariables< MeshType >& conservativeVariables,
+                                const PointType& center = PointType( 0.0 ) )
+      {
+         typedef Functions::Analytic::VectorNorm< Dimensions, RealType > VectorNormType;
+         typedef Operators::Analytic::Sign< Dimensions, RealType > SignType;
+         typedef Functions::OperatorFunction< SignType, VectorNormType > InitialConditionType;
+         typedef SharedPointer< InitialConditionType, DeviceType > InitialConditionPointer;
+         
+         InitialConditionPointer initialCondition;
+         initialCondition->getFunction().setCenter( center );
+         initialCondition->getFunction().setMaxNorm( true );
+         initialCondition->getFunction().setRadius( discontinuityPlacement[ 0 ] );
+         discontinuityPlacement *= 1.0 / discontinuityPlacement[ 0 ];
+         for( int i = 1; i < Dimensions; i++ )
+            discontinuityPlacement[ i ] = 1.0 / discontinuityPlacement[ i ];
+         initialCondition->getFunction().setAnisotropy( discontinuityPlacement );
+         initialCondition->getFunction().setMultiplicator( -1.0 );
+         
+         Functions::MeshFunctionEvaluator< MeshFunctionType, InitialConditionType > evaluator;
+
+         /****
+          * Density
+          */
+         initialCondition->getOperator().setPositiveValue( leftDensity );
+         initialCondition->getOperator().setNegativeValue( rightDensity );
+         evaluator.evaluate( conservativeVariables.getDensity(), initialCondition );
+         conservativeVariables.getDensity()->write( "density.gplt", "gnuplot" );
+         
+         /****
+          * Momentum
+          */
+         for( int i = 0; i < Dimensions; i++ )
+         {
+            initialCondition->getOperator().setPositiveValue( leftDensity * leftVelocity[ i ] );
+            initialCondition->getOperator().setNegativeValue( rightDensity * rightVelocity[ i ] );
+            evaluator.evaluate( ( *conservativeVariables.getMomentum() )[ i ], initialCondition );
+         }
+         
+         /****
+          * Energy
+          */
+         const RealType leftKineticEnergy = leftVelocity.lpNorm( 2.0 );
+         const RealType rightKineticEnergy = rightVelocity.lpNorm( 2.0 );
+         const RealType leftEnergy = leftPressure / ( gamma - 1.0 ) + 0.5 * leftDensity * leftKineticEnergy * leftKineticEnergy;
+         const RealType rightEnergy = rightPressure / ( gamma - 1.0 ) + 0.5 * rightDensity * rightKineticEnergy * rightKineticEnergy;
+         initialCondition->getOperator().setPositiveValue( leftEnergy );
+         initialCondition->getOperator().setNegativeValue( rightEnergy );
+         evaluator.evaluate( conservativeVariables.getEnergy(), initialCondition );
+         conservativeVariables.getEnergy()->write( "energy-init", "gnuplot" );
+      }
+      
+      
+   protected:
+      
+      PointType discontinuityPlacement;
+      
+      RealType leftDensity, rightDensity;
+      PointType leftVelocity, rightVelocity;
+      RealType leftPressure, rightPressure;
+      
+      RealType gamma; // gamma in the ideal gas state equation
+};
+
+} //namespace TNL
\ No newline at end of file
diff --git a/examples/inviscid-flow/1d/euler.cpp b/examples/inviscid-flow/euler.cpp
similarity index 100%
rename from examples/inviscid-flow/1d/euler.cpp
rename to examples/inviscid-flow/euler.cpp
diff --git a/examples/inviscid-flow/1d/euler.cu b/examples/inviscid-flow/euler.cu
similarity index 100%
rename from examples/inviscid-flow/1d/euler.cu
rename to examples/inviscid-flow/euler.cu
diff --git a/examples/inviscid-flow/1d/euler.h b/examples/inviscid-flow/euler.h
similarity index 77%
rename from examples/inviscid-flow/1d/euler.h
rename to examples/inviscid-flow/euler.h
index b5e1124eb20a09db397c117414f90ed7fad18132..b3fc08683f566bc169ff3b134fc4572005c804fa 100644
--- a/examples/inviscid-flow/1d/euler.h
+++ b/examples/inviscid-flow/euler.h
@@ -5,23 +5,22 @@
 #include <TNL/Operators/NeumannBoundaryConditions.h>
 #include <TNL/Functions/Analytic/Constant.h>
 #include "eulerProblem.h"
-#include "LaxFridrichs1D.h"
-#include "MyMixedBoundaryConditions.h"
-#include "MyNeumannBoundaryConditions.h"
-
+#include "LaxFridrichs.h"
 #include "eulerRhs.h"
 #include "eulerBuildConfigTag.h"
 
+#include "RiemannProblemInitialCondition.h"
+
 using namespace TNL;
 
 typedef eulerBuildConfigTag BuildConfig;
 
 /****
- * Uncoment the following (and comment the previous line) for the complete build.
+ * Uncomment 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,
+ * especially if CUDA is enabled. Use this, if you want, only for the final build,
  * not in the development phase.
  */
 //typedef tnlDefaultConfigTag BuildConfig;
@@ -31,21 +30,16 @@ template< typename ConfigTag >class eulerConfig
    public:
       static void configSetup( Config::ConfigDescription & config )
       {
-         config.addDelimiter( "euler settings:" );
+         config.addDelimiter( "Inviscid flow settings:" );
          config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
             config.addEntryEnum< String >( "dirichlet" );
             config.addEntryEnum< String >( "neumann" );
             config.addEntryEnum< String >( "mymixed" );
             config.addEntryEnum< String >( "myneumann" );
          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." );
+         typedef Meshes::Grid< 3 > Mesh;
+         LaxFridrichs< Mesh >::configSetup( config, "inviscid-operators-" );
+         RiemannProblemInitialCondition< Mesh >::configSetup( config );
 
          /****
           * Add definition of your solver command line arguments.
@@ -70,10 +64,10 @@ class eulerSetter
 
       static bool run( const Config::ParameterContainer & parameters )
       {
-          enum { Dimensions = MeshType::getMeshDimensions() };
-          typedef LaxFridrichs1D< MeshType, Real, Index > ApproximateOperator;
+          enum { Dimension = MeshType::getMeshDimension() };
+          typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator;
           typedef eulerRhs< MeshType, Real > RightHandSide;
-          typedef Containers::StaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+          typedef Containers::StaticVector < MeshType::getMeshDimension(), Real > Point;
 
          /****
           * Resolve the template arguments of your solver here.
@@ -83,10 +77,10 @@ class eulerSetter
           String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
           if( parameters.checkParameter( "boundary-conditions-constant" ) )
           {
-             typedef Functions::Analytic::Constant< Dimensions, Real > Constant;
+             typedef Functions::Analytic::Constant< Dimension, Real > Constant;
              if( boundaryConditionsType == "dirichlet" )
              {
-                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
                 typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
                 SolverStarter solverStarter;
                 return solverStarter.template run< Problem >( parameters );
@@ -99,7 +93,7 @@ class eulerSetter
           typedef Functions::MeshFunction< MeshType > MeshFunction;
           if( boundaryConditionsType == "dirichlet" )
           {
-             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
              typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
              SolverStarter solverStarter;
              return solverStarter.template run< Problem >( parameters );
@@ -137,5 +131,3 @@ int main( int argc, char* argv[] )
       return EXIT_FAILURE;
    return EXIT_SUCCESS;
 }
-
-
diff --git a/examples/inviscid-flow/2d/eulerBuildConfigTag.h b/examples/inviscid-flow/eulerBuildConfigTag.h
similarity index 84%
rename from examples/inviscid-flow/2d/eulerBuildConfigTag.h
rename to examples/inviscid-flow/eulerBuildConfigTag.h
index b3727450de5e7030b04bed15f31bfd5ab8a6fbe9..b219ba4ff58c0c6601f7393e93ee395fa18ce6f8 100644
--- a/examples/inviscid-flow/2d/eulerBuildConfigTag.h
+++ b/examples/inviscid-flow/eulerBuildConfigTag.h
@@ -21,14 +21,14 @@ template<> struct ConfigTagReal< eulerBuildConfigTag, long double > { enum { ena
 template<> struct ConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; };
 template<> struct ConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; };
 
-template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 2 ) }; };
+template< int Dimension > struct ConfigTagDimension< eulerBuildConfigTag, Dimension >{ enum { enabled = ( Dimension == 1 ) }; };
 
 /****
  * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
  */
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< eulerBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled  &&
+template< int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< eulerBuildConfigTag, Meshes::Grid< Dimension, Real, Device, Index > >
+      { enum { enabled = ConfigTagDimension< eulerBuildConfigTag, Dimension >::enabled  &&
                          ConfigTagReal< eulerBuildConfigTag, Real >::enabled &&
                          ConfigTagDevice< eulerBuildConfigTag, Device >::enabled &&
                          ConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; };
@@ -48,5 +48,4 @@ template<> struct ConfigTagExplicitSolver< eulerBuildConfigTag, ExplicitEulerSol
 } // namespace Solvers
 } // namespace TNL
 
-
 #endif /* eulerBUILDCONFIGTAG_H_ */
diff --git a/examples/inviscid-flow/2d/eulerProblem.h b/examples/inviscid-flow/eulerProblem.h
similarity index 66%
rename from examples/inviscid-flow/2d/eulerProblem.h
rename to examples/inviscid-flow/eulerProblem.h
index 57518d426d9310488f8aa9647ea923722fc34004..ea9e3155641613eb0cb20712fbc1416d883e1de5 100644
--- a/examples/inviscid-flow/2d/eulerProblem.h
+++ b/examples/inviscid-flow/eulerProblem.h
@@ -1,7 +1,19 @@
+/***************************************************************************
+                          eulerProblem.h  -  description
+                             -------------------
+    begin                : Feb 13, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
 #pragma once
 
 #include <TNL/Problems/PDEProblem.h>
 #include <TNL/Functions/MeshFunction.h>
+#include "CompressibleConservativeVariables.h"
+
 
 using namespace TNL::Problems;
 
@@ -10,24 +22,19 @@ namespace TNL {
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-           typename DifferentialOperator >
+          typename InviscidOperators >
 class eulerProblem:
    public PDEProblem< Mesh,
-                         typename DifferentialOperator::RealType,
-                         typename Mesh::DeviceType,
-                         typename DifferentialOperator::IndexType >
+                      typename InviscidOperators::RealType,
+                      typename Mesh::DeviceType,
+                      typename InviscidOperators::IndexType >
 {
    public:
-
-      typedef typename DifferentialOperator::RealType RealType;
+      
+      typedef typename InviscidOperators::RealType RealType;
       typedef typename Mesh::DeviceType DeviceType;
-      typedef typename DifferentialOperator::IndexType IndexType;
-      typedef Functions::MeshFunction< Mesh > MeshFunctionType;
-      typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer;
-      typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer;
-      typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer;
-      typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
-      typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;      
+      typedef typename InviscidOperators::IndexType IndexType;
+      typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;
       
       using typename BaseType::MeshType;
       using typename BaseType::MeshPointer;
@@ -36,13 +43,17 @@ class eulerProblem:
       using typename BaseType::MeshDependentDataType;
       using typename BaseType::MeshDependentDataPointer;
 
-      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::Pressure Pressure;
+      static const int Dimensions = Mesh::getMeshDimension();      
+
+      typedef Functions::MeshFunction< Mesh > MeshFunctionType;
+      typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType;
+      typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType;
+      typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer;
+      typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer;
+      typedef SharedPointer< VelocityFieldType > VelocityFieldPointer;
+      typedef SharedPointer< InviscidOperators > InviscidOperatorsPointer;
+      typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer;
+      typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
 
       static String getTypeStatic();
 
@@ -75,7 +86,7 @@ class eulerProblem:
       void bindDofs( const MeshPointer& mesh,
                      DofVectorPointer& dofs );
 
-      void getExplicitRHS( const RealType& time,
+      void getExplicitUpdate( const RealType& time,
                            const RealType& tau,
                            const MeshPointer& mesh,
                            DofVectorPointer& _u,
@@ -99,17 +110,18 @@ class eulerProblem:
 
    protected:
 
-      DifferentialOperatorPointer differentialOperatorPointer;
+      InviscidOperatorsPointer inviscidOperatorsPointer;
+         
       BoundaryConditionPointer boundaryConditionPointer;
       RightHandSidePointer rightHandSidePointer;
-
-      MeshFunctionPointer uRho, uRhoVelocityX, uRhoVelocityY, uEnergy;
-      MeshFunctionPointer fuRho, fuRhoVelocityX, fuRhoVelocityY, fuEnergy;
       
-      MeshFunctionPointer pressure, velocity, velocityX, velocityY;
+      ConservativeVariablesPointer conservativeVariables,
+                                   conservativeVariablesRHS;
       
-      RealType gamma;
-
+      VelocityFieldPointer velocity;
+      MeshFunctionPointer pressure;
+      
+      RealType gamma;          
 };
 
 } // namespace TNL
diff --git a/examples/inviscid-flow/eulerProblem_impl.h b/examples/inviscid-flow/eulerProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0ab4e553aba1672a2649061c1d51e9d71ccb201
--- /dev/null
+++ b/examples/inviscid-flow/eulerProblem_impl.h
@@ -0,0 +1,416 @@
+/***************************************************************************
+                          eulerProblem_impl.h  -  description
+                             -------------------
+    begin                : Feb 13, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/FileName.h>
+#include <TNL/Matrices/MatrixSetter.h>
+#include <TNL/Solvers/PDE/ExplicitUpdater.h>
+#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
+#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
+#include <TNL/Functions/Analytic/VectorNorm.h>
+
+#include "RiemannProblemInitialCondition.h"
+#include "CompressibleConservativeVariables.h"
+#include "PhysicalVariablesGetter.h"
+#include "eulerProblem.h"
+
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsEnergy.h"
+#include "LaxFridrichsMomentumX.h"
+#include "LaxFridrichsMomentumY.h"
+#include "LaxFridrichsMomentumZ.h"
+
+namespace TNL {
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+String
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+getTypeStatic()
+{
+   return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+String
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+getPrologHeader() const
+{
+   return String( "Inviscid flow solver" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+writeProlog( Logger& logger, const Config::ParameterContainer& 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 InviscidOperators >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+setup( const MeshPointer& meshPointer,
+       const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   if( ! this->inviscidOperatorsPointer->setup( meshPointer, parameters, prefix + "inviscid-operators-" ) ||
+       ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ||
+       ! this->rightHandSidePointer->setup( parameters, prefix + "right-hand-side-" ) )
+      return false;
+   this->gamma = parameters.getParameter< double >( "gamma" );
+   velocity->setMesh( meshPointer );
+   pressure->setMesh( meshPointer );
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::IndexType
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+getDofs( const MeshPointer& mesh ) const
+{
+   /****
+    * Return number of  DOFs (degrees of freedom) i.e. number
+    * of unknowns to be resolved by the main solver.
+    */
+   return this->conservativeVariables->getDofs( mesh );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+bindDofs( const MeshPointer& mesh,
+          DofVectorPointer& dofVector )
+{
+   this->conservativeVariables->bind( mesh, dofVector );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+setInitialCondition( const Config::ParameterContainer& parameters,
+                     const MeshPointer& mesh,
+                     DofVectorPointer& dofs,
+                     MeshDependentDataPointer& meshDependentData )
+{
+   CompressibleConservativeVariables< MeshType > conservativeVariables;
+   conservativeVariables.bind( mesh, dofs );
+   const String& initialConditionType = parameters.getParameter< String >( "initial-condition" );
+   if( initialConditionType == "riemann-problem" )
+   {
+      RiemannProblemInitialCondition< MeshType > initialCondition;
+      if( ! initialCondition.setup( parameters ) )
+         return false;
+      initialCondition.setInitialCondition( conservativeVariables );
+      return true;
+   }
+   std::cerr << "Unknown initial condition " << initialConditionType << std::endl;
+   return false;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+   template< typename Matrix >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+setupLinearSystem( const MeshPointer& mesh,
+                   Matrix& matrix )
+{
+/*   const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::CompressedRowLengthsVector CompressedRowLengthsVectorType;
+   CompressedRowLengthsVectorType rowLengths;
+   if( ! rowLengths.setSize( dofs ) )
+      return false;
+   MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >( mesh,
+                                                                          differentialOperator,
+                                                                          boundaryCondition,
+                                                                          rowLengths );
+   matrix.setDimensions( dofs, dofs );
+   if( ! matrix.setCompressedRowLengths( rowLengths ) )
+      return false;*/
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+makeSnapshot( const RealType& time,
+              const IndexType& step,
+              const MeshPointer& mesh,
+              DofVectorPointer& dofs,
+              MeshDependentDataPointer& meshDependentData )
+{
+  std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
+  
+  this->bindDofs( mesh, dofs );
+  PhysicalVariablesGetter< MeshType > physicalVariablesGetter;
+  physicalVariablesGetter.getVelocity( this->conservativeVariables, this->velocity );
+  physicalVariablesGetter.getPressure( this->conservativeVariables, this->gamma, this->pressure );
+  
+   FileName fileName;
+   fileName.setExtension( "tnl" );
+   fileName.setIndex( step );
+   fileName.setFileNameBase( "density-" );
+   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
+      return false;
+   
+   fileName.setFileNameBase( "velocity-" );
+   if( ! this->velocity->save( fileName.getFileName() ) )
+      return false;
+
+   fileName.setFileNameBase( "pressure-" );
+   if( ! this->pressure->save( fileName.getFileName() ) )
+      return false;
+
+   fileName.setFileNameBase( "energy-" );
+   if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
+      return false;
+   
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+getExplicitUpdate( const RealType& time,
+                   const RealType& tau,
+                   const MeshPointer& mesh,
+                   DofVectorPointer& _u,
+                   DofVectorPointer& _fu,
+                   MeshDependentDataPointer& meshDependentData )
+{
+    typedef typename MeshType::Cell Cell;
+    
+    /****
+     * Bind DOFs
+     */
+    this->conservativeVariables->bind( mesh, _u );
+    this->conservativeVariablesRHS->bind( mesh, _fu );
+    this->velocity->setMesh( mesh );
+    this->pressure->setMesh( mesh );
+    
+    /****
+     * Resolve the physical variables
+     */
+    PhysicalVariablesGetter< typename MeshPointer::ObjectType > physicalVariables;
+    physicalVariables.getVelocity( this->conservativeVariables, this->velocity );
+    physicalVariables.getPressure( this->conservativeVariables, this->gamma, this->pressure );
+    
+   /****
+    * Set-up operators
+    */
+   typedef typename InviscidOperators::ContinuityOperatorType ContinuityOperatorType;
+   typedef typename InviscidOperators::MomentumXOperatorType MomentumXOperatorType;
+   typedef typename InviscidOperators::MomentumYOperatorType MomentumYOperatorType;
+   typedef typename InviscidOperators::MomentumZOperatorType MomentumZOperatorType;
+   typedef typename InviscidOperators::EnergyOperatorType EnergyOperatorType;
+    
+    this->inviscidOperatorsPointer->setTau( tau );
+    this->inviscidOperatorsPointer->setVelocity( this->velocity );
+    this->inviscidOperatorsPointer->setPressure( this->pressure );
+
+   /****
+    * Continuity equation
+    */ 
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, ContinuityOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; 
+   explicitUpdaterContinuity.setDifferentialOperator( this->inviscidOperatorsPointer->getContinuityOperator() );
+   explicitUpdaterContinuity.setBoundaryConditions( this->boundaryConditionPointer );
+   explicitUpdaterContinuity.setRightHandSide( this->rightHandSidePointer );
+   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time, tau, mesh, 
+                                                                     this->conservativeVariables->getDensity(),
+                                                                     this->conservativeVariablesRHS->getDensity() );
+
+   /****
+    * Momentum equations
+    */
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumXOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumX; 
+   explicitUpdaterMomentumX.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumXOperator() );
+   explicitUpdaterMomentumX.setBoundaryConditions( this->boundaryConditionPointer );
+   explicitUpdaterMomentumX.setRightHandSide( this->rightHandSidePointer );   
+   explicitUpdaterMomentumX.template update< typename Mesh::Cell >( time, tau, mesh,
+                                                           ( *this->conservativeVariables->getMomentum() )[ 0 ], // uRhoVelocityX,
+                                                           ( *this->conservativeVariablesRHS->getMomentum() )[ 0 ] ); //, fuRhoVelocityX );
+
+   if( Dimensions > 1 )
+   {
+      Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumYOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY;
+      explicitUpdaterMomentumY.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumYOperator() );
+      explicitUpdaterMomentumY.setBoundaryConditions( this->boundaryConditionPointer );
+      explicitUpdaterMomentumY.setRightHandSide( this->rightHandSidePointer );         
+      explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time, tau, mesh,
+                                                              ( *this->conservativeVariables->getMomentum() )[ 1 ], // uRhoVelocityX,
+                                                              ( *this->conservativeVariablesRHS->getMomentum() )[ 1 ] ); //, fuRhoVelocityX );
+   }
+   
+   if( Dimensions > 2 )
+   {
+      Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumZOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumZ;
+      explicitUpdaterMomentumZ.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumZOperator() );
+      explicitUpdaterMomentumZ.setBoundaryConditions( this->boundaryConditionPointer );
+      explicitUpdaterMomentumZ.setRightHandSide( this->rightHandSidePointer );               
+      explicitUpdaterMomentumZ.template update< typename Mesh::Cell >( time, tau, mesh,
+                                                              ( *this->conservativeVariables->getMomentum() )[ 2 ], // uRhoVelocityX,
+                                                              ( *this->conservativeVariablesRHS->getMomentum() )[ 2 ] ); //, fuRhoVelocityX );
+   }
+   
+  
+   /****
+    * Energy equation
+    */
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, EnergyOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
+   explicitUpdaterEnergy.setDifferentialOperator( this->inviscidOperatorsPointer->getEnergyOperator() );
+   explicitUpdaterEnergy.setBoundaryConditions( this->boundaryConditionPointer );
+   explicitUpdaterEnergy.setRightHandSide( this->rightHandSidePointer );                  
+   explicitUpdaterEnergy.template update< typename Mesh::Cell >( time, tau, mesh,
+                                                           this->conservativeVariables->getEnergy(), // uRhoVelocityX,
+                                                           this->conservativeVariablesRHS->getEnergy() ); //, fuRhoVelocityX );
+   
+   /*this->conservativeVariablesRHS->getDensity()->write( "density", "gnuplot" );
+   this->conservativeVariablesRHS->getEnergy()->write( "energy", "gnuplot" );
+   this->conservativeVariablesRHS->getMomentum()->write( "momentum", "gnuplot", 0.05 );
+   getchar();*/
+
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename InviscidOperators >
+   template< typename Matrix >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshPointer& mesh,
+                      DofVectorPointer& _u,
+                      Matrix& matrix,
+                      DofVectorPointer& b,
+                      MeshDependentDataPointer& meshDependentData )
+{
+/*   LinearSystemAssembler< Mesh,
+                             MeshFunctionType,
+                             InviscidOperators,
+                             BoundaryCondition,
+                             RightHandSide,
+                             BackwardTimeDiscretisation,
+                             Matrix,
+                             DofVectorType > systemAssembler;
+
+   MeshFunction< 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 InviscidOperators >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
+postIterate( const RealType& time,
+             const RealType& tau,
+             const MeshPointer& mesh,
+             DofVectorPointer& dofs,
+             MeshDependentDataPointer& 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);
+//   OperatorFunction< VelocityX, MeshFunction, void, true > OFVelocityX;
+//   velocityX = OFVelocityX;
+
+   //velocityY
+   euler2DVelocityY.setRhoVelY(uRhoVelocityY);
+   euler2DVelocityY.setRho(uRho);
+//   OperatorFunction< VelocityY, MeshFunction, void, time > OFVelocityY;
+//   velocityY = OFVelocityY;
+
+   //velocity
+   euler2DVelocity.setVelX(velocityX);
+   euler2DVelocity.setVelY(velocityY);
+//   OperatorFunction< Velocity, MeshFunction, void, time > OFVelocity;
+//   velocity = OFVelocity;
+
+   //pressure
+   euler2DPressure.setGamma(gamma);
+   euler2DPressure.setVelocity(velocity);
+   euler2DPressure.setEnergy(uEnergy);
+   euler2DPressure.setRho(uRho);
+//   OperatorFunction< euler2DPressure, MeshFunction, void, time > OFPressure;
+//   pressure = OFPressure;
+    */
+   return true;
+}
+
+} // namespace TNL
+
diff --git a/examples/inviscid-flow/2d/eulerRhs.h b/examples/inviscid-flow/eulerRhs.h
similarity index 76%
rename from examples/inviscid-flow/2d/eulerRhs.h
rename to examples/inviscid-flow/eulerRhs.h
index 1b46dc831fe9daa6133ff32ee4bea5faf4eb8d1c..51d4e024398d579f49c158292e2890536a1e319c 100644
--- a/examples/inviscid-flow/2d/eulerRhs.h
+++ b/examples/inviscid-flow/eulerRhs.h
@@ -6,7 +6,7 @@
 namespace TNL {
 
 template< typename Mesh, typename Real >class eulerRhs
-  : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > 
+  : public Functions::Domain< Mesh::getMeshDimension(), Functions::MeshDomain > 
  {
    public:
 
@@ -24,8 +24,8 @@ template< typename Mesh, typename Real >class eulerRhs
       Real operator()( const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         typedef typename MeshEntity::MeshType::VertexType VertexType;
-         VertexType v = entity.getCenter();
+         typedef typename MeshEntity::MeshType::PointType PointType;
+         PointType v = entity.getCenter();
          return 0.0;
       }
 };
diff --git a/examples/inviscid-flow/run-euler b/examples/inviscid-flow/run-euler
new file mode 100644
index 0000000000000000000000000000000000000000..7af3493805c96e19c65a3f475e2ed63aaf59db92
--- /dev/null
+++ b/examples/inviscid-flow/run-euler
@@ -0,0 +1,35 @@
+#!/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
+tnl-euler-2d --initial-condition riemann-problem \
+             --discontinuity-placement-0 0.3 \
+             --discontinuity-placement-1 0.3 \
+             --discontinuity-placement-2 0.3 \
+             --left-density 1.0 \
+             --right-density 1.0 \
+             --left-velocity-0 -0.2 \
+             --left-velocity-1 -0.2 \
+             --left-velocity-2 -0.2 \
+             --right-velocity-0 0.2 \
+             --right-velocity-1 0.2 \
+             --right-velocity-2 0.2 \
+             --left-pressure 0.4 \
+             --right-pressure 0.4 \
+             --time-discretisation explicit \
+             --boundary-conditions-type neumann \
+             --boundary-conditions-constant 0 \
+             --discrete-solver euler \
+             --time-step 0.0001 \
+             --snapshot-period 0.01 \
+             --final-time 1.0
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/mean-curvature-flow/CMakeLists.txt b/examples/mean-curvature-flow/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h
index a1dfe65f3416cae2039a4e44c1ccc91f13d5b4b1..4d852a7d8358666d66b4482232649616cb9b5a32 100644
--- a/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h
@@ -69,8 +69,8 @@ class meanCurvatureFlowEocSetter
    typedef Device DeviceType;
    typedef Index IndexType;
 
-   typedef typename MeshType::VertexType Vertex;
-   enum { Dimensions = MeshType::meshDimensions };
+   typedef typename MeshType::PointType Point;
+   enum { Dimension = MeshType::getMeshDimension() };
 
    static bool run( const Config::ParameterContainer& parameters )
    {
@@ -78,11 +78,11 @@ class meanCurvatureFlowEocSetter
       typedef tnlFiniteVolumeOperatorQ<MeshType, Real, Index, 0> OperatorQ;
       typedef FiniteVolumeNonlinearOperator<MeshType, OperatorQ, Real, Index > NonlinearOperator;
       typedef NonlinearDiffusion< MeshType, NonlinearOperator, Real, Index > ApproximateOperator;
-      typedef ExactNonlinearDiffusion< ExactGradientNorm< Dimensions >, Dimensions > ExactOperator;
-      typedef TestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
-      typedef MeanCurvatureFlowEocRhs< ExactOperator, TestFunction, Dimensions > RightHandSide;
-      typedef StaticVector < MeshType::meshDimensions, Real > Vertex;
-      typedef DirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
+      typedef ExactNonlinearDiffusion< ExactGradientNorm< Dimension >, Dimension > ExactOperator;
+      typedef TestFunction< MeshType::getMeshDimension(), Real, Device > TestFunction;
+      typedef MeanCurvatureFlowEocRhs< ExactOperator, TestFunction, Dimension > RightHandSide;
+      typedef StaticVector < MeshType::getMeshDimension(), Real > Point;
+      typedef DirichletBoundaryConditions< MeshType, TestFunction, Dimension, Real, Index > BoundaryConditions;
       typedef MeanCurvatureFlowEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
       SolverStarter solverStarter;
       return solverStarter.template run< Solver >( parameters );
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow.h b/examples/mean-curvature-flow/tnl-mean-curvature-flow.h
index 7a284907c171e7b413a87e4103fa497c42553799..f2abd1671010c14207818909c0ca4c6e5e82b792 100644
--- a/examples/mean-curvature-flow/tnl-mean-curvature-flow.h
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow.h
@@ -70,8 +70,8 @@ class meanCurvatureFlowSetter
    typedef Device DeviceType;
    typedef Index IndexType;
 
-   typedef typename MeshType::VertexType Vertex;
-   enum { Dimensions = MeshType::meshDimensions };
+   typedef typename MeshType::PointType Point;
+   enum { Dimension = MeshType::getMeshDimension() };
 
    static bool run( const Config::ParameterContainer& parameters )
    {
@@ -101,16 +101,16 @@ class meanCurvatureFlowSetter
    static bool setBoundaryConditions( const Config::ParameterContainer& parameters )
    {
       typedef OneSidedNonlinearDiffusion< MeshType, NonlinearOperator, Real, Index > ApproximateOperator;
-      typedef Constant< Dimensions, Real > RightHandSide;
-      typedef StaticVector< MeshType::meshDimensions, Real > Vertex;
+      typedef Constant< Dimension, Real > RightHandSide;
+      typedef StaticVector< MeshType::getMeshDimension(), Real > Point;
 
       String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
       if( parameters.checkParameter( "boundary-conditions-constant" ) )
       {
-         typedef Constant< Dimensions, Real > Constant;
+         typedef Constant< Dimension, Real > Constant;
          if( boundaryConditionsType == "dirichlet" )
          {
-            typedef DirichletBoundaryConditions< MeshType, Constant, Dimensions, Real, Index > BoundaryConditions;
+            typedef DirichletBoundaryConditions< MeshType, Constant, Dimension, Real, Index > BoundaryConditions;
             typedef MeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
             SolverStarter solverStarter;
             return solverStarter.template run< Solver >( parameters );
@@ -124,7 +124,7 @@ class meanCurvatureFlowSetter
       typedef Functions::MeshFunction< MeshType > MeshFunction;
       if( boundaryConditionsType == "dirichlet" )
       {
-         typedef DirichletBoundaryConditions< MeshType, MeshFunction, Dimensions, Real, Index > BoundaryConditions;
+         typedef DirichletBoundaryConditions< MeshType, MeshFunction, Dimension, Real, Index > BoundaryConditions;
          typedef MeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
          SolverStarter solverStarter;
          return solverStarter.template run< Solver >( parameters );
diff --git a/examples/narrow-band/CMakeLists.txt b/examples/narrow-band/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..748343b58e4c5bcca2fe5de2160d3e4a2eeb2e76
--- /dev/null
+++ b/examples/narrow-band/CMakeLists.txt
@@ -0,0 +1,22 @@
+set( tnl_narrow_band_SOURCES
+#     MainBuildConfig.h
+#     tnlNarrowBand2D_impl.h
+#     tnlNarrowBand.h
+#     narrowBandConfig.h 
+     main.cpp)
+
+
+IF(  BUILD_CUDA ) 
+	CUDA_ADD_EXECUTABLE(narrow-band${debugExt} main.cu)
+ELSE(  BUILD_CUDA )                
+	ADD_EXECUTABLE(narrow-band${debugExt} main.cpp)
+ENDIF( BUILD_CUDA )
+target_link_libraries (narrow-band${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS narrow-band${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+#INSTALL( FILES ${tnl_narrow_band_SOURCES}
+#         DESTINATION share/tnl-${tnlVersion}/examples/narrow-band )
diff --git a/examples/narrow-band/MainBuildConfig.h b/examples/narrow-band/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/examples/narrow-band/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/examples/narrow-band/main.cpp b/examples/narrow-band/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/examples/narrow-band/main.cpp
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/examples/narrow-band/main.cu b/examples/narrow-band/main.cu
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/examples/narrow-band/main.cu
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/examples/narrow-band/main.h b/examples/narrow-band/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9f55656f1128eb268214eb85a4bc7fe26ec5773
--- /dev/null
+++ b/examples/narrow-band/main.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+                          main.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "MainBuildConfig.h"
+	//for HOST versions:
+//#include "tnlNarrowBand.h"
+	//for DEVICE versions:
+#include "tnlNarrowBand_CUDA.h"
+#include "narrowBandConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+
+#include <mesh/tnlGrid.h>
+#include <core/tnlDevice.h>
+#include <time.h>
+#include <ctime>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+	time_t start;
+	time_t stop;
+	time(&start);
+	std::clock_t start2= std::clock();
+   Config::ParameterContainer parameters;
+   tnlConfigDescription configDescription;
+   narrowBandConfig< BuildConfig >::configSetup( configDescription );
+
+   if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
+      return false;
+
+   const int& dim = parameters.getParameter< int >( "dim" );
+
+   if(dim == 2)
+   {
+		tnlNarrowBand<tnlGrid<2,double,TNL::Devices::Host, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		TNL_CHECK_CUDA_DEVICE;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+//   else if(dim == 3)
+//   {
+//		tnlNarrowBand<tnlGrid<3,double,TNL::Devices::Host, int>, double, int> solver;
+//		if(!solver.init(parameters))
+//	   {
+//			cerr << "Solver failed to initialize." << endl;
+//			return EXIT_FAILURE;
+//	   }
+//		TNL_CHECK_CUDA_DEVICE;
+//	   cout << "-------------------------------------------------------------" << endl;
+//	   cout << "Starting solver..." << endl;
+//	   solver.run();
+//   }
+   else
+   {
+	   cerr << "Unsupported number of dimensions: " << dim << "!" << endl;
+	   return EXIT_FAILURE;
+   }
+
+
+   time(&stop);
+   cout << "Solver stopped..." << endl;
+   cout << endl;
+   cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/examples/narrow-band/narrowBandConfig.h b/examples/narrow-band/narrowBandConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..bab58ceac46bf9c766b697ed79c2c676111323a2
--- /dev/null
+++ b/examples/narrow-band/narrowBandConfig.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+                          narrowBandConfig.h  -  description
+                             -------------------
+    begin                : Oct 15, 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 NARROWBANDCONFIG_H_
+#define NARROWBANDCONFIG_H_
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class narrowBandConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Narrow Band Solver solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" );
+         config.addRequiredEntry        < String > ( "initial-condition", "Initial condition for solver");
+         config.addRequiredEntry        < int > ( "dim", "Dimension of problem.");
+         config.addRequiredEntry        < double > ( "tau", "Time step.");
+         config.addRequiredEntry        < double > ( "final-time", "Final time.");
+         config.addEntry       < String > ( "mesh", "Name of mesh.", "mesh.tnl" );
+         config.addEntry       < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" );
+      }
+};
+
+#endif /* NARROWBANDCONFIG_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand.h b/examples/narrow-band/tnlNarrowBand.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d3d19bc03b43247f735cf04c5c82368360a748d
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+                          tnlNarrowBand.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND_H_
+#define TNLNARROWBAND_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+#ifdef HAVE_OPENMP
+#include <omp.h>
+#endif
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlNarrowBand
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+	tnlNarrowBand();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+
+	void setupSquare1000(Index i, Index j);
+	void setupSquare1100(Index i, Index j);
+	void setupSquare1010(Index i, Index j);
+	void setupSquare1001(Index i, Index j);
+	void setupSquare1110(Index i, Index j);
+	void setupSquare1101(Index i, Index j);
+	void setupSquare1011(Index i, Index j);
+	void setupSquare1111(Index i, Index j);
+	void setupSquare0000(Index i, Index j);
+	void setupSquare0100(Index i, Index j);
+	void setupSquare0010(Index i, Index j);
+	void setupSquare0001(Index i, Index j);
+	void setupSquare0110(Index i, Index j);
+	void setupSquare0101(Index i, Index j);
+	void setupSquare0011(Index i, Index j);
+	void setupSquare0111(Index i, Index j);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity;
+
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlNarrowBand();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j, const Index k);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity;
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+	//for single core version use this implementation:
+#include "tnlNarrowBand2D_impl.h"
+	//for parallel version use this one instead:
+// #include "tnlNarrowBand2D_openMP_impl.h"
+
+#include "tnlNarrowBand3D_impl.h"
+
+#endif /* TNLNARROWBAND_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..310d0fb239260fcc740a0f2bc56b37a36662a2f6
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h
@@ -0,0 +1,1317 @@
+/***************************************************************************
+                          tnlNarrowBand2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND2D_IMPL_H_
+#define TNLNARROWBAND2D_IMPL_H_
+
+#define NARROWBAND_SUBGRID_SIZE 32
+
+#include "tnlNarrowBand.h"
+
+#ifdef HAVE_CUDA
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+#endif
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real  tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return -arg;
+	return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlNarrowBand< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand()
+:dofVector(Mesh)
+{
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	//Entity.refresh();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+	tau = parameters.getParameter< double >( "tau" );
+
+	finalTime = parameters.getParameter< double >( "final-time" );
+
+	statusGridSize = ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaStatusVector),  statusGridSize*statusGridSize*sizeof(int));
+//	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(),  statusGridSize*statusGridSize* sizeof(int)), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&reinitialize, sizeof(int));
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+#endif
+
+	int n = Mesh.getDimensions().x();
+
+	dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocks2(statusGridSize ,statusGridSize);
+	initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+
+	/*dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);*/
+	initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+
+	cout << "Solver initialized." << endl;
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlockFS(1, 512);
+	dim3 numBlocksFS(4,1);
+	dim3 threadsPerBlockNB(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocksNB(n/NARROWBAND_SUBGRID_SIZE + 1,n/NARROWBAND_SUBGRID_SIZE + 1);
+
+	double time = 0.0;
+	int reinit = 0;
+
+	cout << "Hi!" << endl;
+	runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	cout << "Hi2!" << endl;
+	while(time < finalTime)
+	{
+		if(tau+time > finalTime)
+			tau=finalTime-time;
+
+		runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		time += tau;
+
+
+		cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		if(reinit != 0 /*&& time != finalTime */)
+		{
+			cout << time << endl;
+
+			initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+		}
+	}
+
+	//data.setLike(dofVector.getData());
+	//cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	//data.save("u-00001.tnl");
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+	//								8 - to the east of curve, 	16 - to the west of curve.
+	int subgridID = i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * statusGridSize;
+	if(cudaStatusVector[subgridID] != 0 && i<Mesh.getDimensions().x() && j < Mesh.getDimensions().y())
+	{
+		tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+		Entity.setCoordinates(CoordinatesType(i,j));
+		Entity.refresh();
+		tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real a,b, tmp;
+
+		if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9))*/ )
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17))*/ )
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 /*|| (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3))*/ )
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5)) */)
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+		}
+
+
+		if(abs(a-b) >= h)
+			tmp = fabsMin(a,b) + sign(value)*h;
+		else
+			tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	//	cudaDofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+		atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp);
+	}
+
+}
+
+
+__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+
+
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+
+	if(solver->Mesh.getDimensions().x() > gx  && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int i = threadIdx.x + blockDim.x*blockIdx.x;
+	int j = blockDim.y*blockIdx.y + threadIdx.y;
+
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	int gid = Entity.getIndex();
+
+	if(abs(cudaDofVector2[gid]) > 1.5*h)
+		cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector2[gid]);
+
+//	if (i >0 && j > 0 && i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y())
+//	{
+//		if(cudaDofVector2[gid]*cudaDofVector2[gid+1] <= 0 )
+//		{
+//			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+//			cudaDofVector2[gid+1] = sign(cudaDofVector2[gid+1])*0.5*h;
+//		}
+//		if( cudaDofVector2[gid]*cudaDofVector2[gid+Mesh.getDimensions().x()] <= 0 )
+//		{
+//			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+//			cudaDofVector2[gid+Mesh.getDimensions().x()] = sign(cudaDofVector2[gid+Mesh.getDimensions().x()])*0.5*h;
+//		}
+//
+//		if(cudaDofVector2[gid]*cudaDofVector2[gid-1] <= 0 )
+//		{
+//			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+//			cudaDofVector2[gid-1] = sign(cudaDofVector2[gid-1])*0.5*h;
+//		}
+//		if( cudaDofVector2[gid]*cudaDofVector2[gid-Mesh.getDimensions().x()] <= 0 )
+//		{
+//			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+//			cudaDofVector2[gid-Mesh.getDimensions().x()] = sign(cudaDofVector2[gid-Mesh.getDimensions().x()])*0.5*h;
+//		}
+//	}
+
+
+//
+
+
+
+
+
+
+//	if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() )
+//	{
+//		if(cudaDofVector[Entity.getIndex()] > 0)
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0001(i,j);
+//					else
+//						setupSquare0000(i,j);
+//				}
+//			}
+//		}
+//
+//	}
+
+	return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	//Real fy = abs(y);
+
+	//Real tmpMin = Min(fx,abs(y));
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+
+	int gx = 0;
+	int gy = threadIdx.y;
+	//if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+	//	return;
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	//int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	//int id1 = gx+gy;
+	//int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+	if(blockIdx.x==0)
+	{
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+
+}
+
+
+
+
+__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	__shared__ double u0;
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+
+//		printf("Hello from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+		if(threadIdx.x+threadIdx.y == 0)
+		{
+//			printf("Hello from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+
+			if(blockIdx.x+blockIdx.y == 0)
+				*(solver->reinitialize) = 0;
+
+			solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] = 0;
+
+			u0 = solver->cudaDofVector2[(blockDim.y*blockIdx.y + 0)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + 0];
+		}
+		__syncthreads();
+
+		double u = solver->cudaDofVector2[(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x];
+
+		if(u*u0 <=0.0)
+			atomicMax(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y]),1);
+	}
+//	if(threadIdx.x+threadIdx.y == 0)
+
+//	printf("Bye from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+
+
+}
+
+
+
+// run this with one thread per block
+__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+//	printf("Hello\n");
+	if(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] == 1)
+	{
+//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+//								8 - to the east of curve, 	16 - to the west of curve.
+			if(blockIdx.x > 0)
+			{
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x - 1 + gridDim.x*blockIdx.y]), 16);
+			}
+
+			if(blockIdx.x < gridDim.x - 1)
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + 1 + gridDim.x*blockIdx.y]), 8);
+
+			if(blockIdx.y > 0 )
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y - 1)]), 4);
+
+			if(blockIdx.y < gridDim.y - 1)
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y + 1)]), 2);
+	}
+
+
+}
+
+
+
+
+
+__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, double tau)
+{
+	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x()+ threadIdx.x;
+	int i = threadIdx.x + blockIdx.x*blockDim.x;
+	int j = threadIdx.y + blockIdx.y*blockDim.y;
+
+//	if(i+j == 0)
+//		printf("Hello\n");
+
+	int blockID = blockIdx.x + blockIdx.y*gridDim.x; /*i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);*/
+
+	int status = solver->cudaStatusVector[blockID];
+
+	if(solver->Mesh.getDimensions().x() > i && solver->Mesh.getDimensions().y() > j)
+	{
+
+		if(status != 0)
+		{
+			tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh);
+			Entity.setCoordinates(Containers::StaticVector<2,double>(i,j));
+			Entity.refresh();
+			tnlNeighborGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+			double value = solver->cudaDofVector2[Entity.getIndex()];
+			double xf,xb,yf,yb, grad, fu, a,b;
+			a = b = 0.0;
+
+			if( i == 0 || (threadIdx.x == 0 && !(status & 9)) )
+			{
+				xb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+				xf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+			else if( i == solver->Mesh.getDimensions().x() - 1 || (threadIdx.x == blockDim.x - 1 && !(status & 17)) )
+			{
+				xb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()] - value;
+			}
+			else
+			{
+				xb =  value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver-> cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+
+			if( j == 0 || (threadIdx.y == 0 && !(status & 3)) )
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] ;
+				yf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			else if( j == solver->Mesh.getDimensions().y() - 1  || (threadIdx.y == blockDim.y - 1 && !(status & 5)) )
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+				yf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()] - value;
+			}
+			else
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0, -1 >()];
+				yf = solver-> cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			__syncthreads();
+
+
+
+
+
+			   if(sign(value) >= 0.0)
+			   {
+				   xf = solver->negativePart(xf);
+
+				   xb = solver->positivePart(xb);
+
+				   yf = solver->negativePart(yf);
+
+				   yb = solver->positivePart(yb);
+
+			   }
+			   else
+			   {
+
+				   xb = solver->negativePart(xb);
+
+				   xf = solver->positivePart(xf);
+
+				   yb = solver->negativePart(yb);
+
+				   yf = solver->positivePart(yf);
+			   }
+
+
+			   if(xb > xf)
+				   a = xb*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+			   else
+				   a = xf*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+
+			   if(yb > yf)
+				   b = yb*solver->Mesh.template getSpaceStepsProducts< 0, -1 >();
+			   else
+				   b = yf*solver->Mesh.template getSpaceStepsProducts< 0, -1 >();
+
+
+
+//			grad = sqrt(0.5 * (xf*xf + xb*xb    +   yf*yf + yb*yb ) )*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+
+			grad = sqrt(/*0.5 **/ (a*a    +   b*b ) );
+
+			fu = -1.0 * grad;
+
+			if((tau*fu+value)*value <=0 )
+			{
+				//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+				//								8 - to the east of curve, 	16 - to the west of curve.
+
+				if((threadIdx.x == 6 && !(status & 9)) && (blockIdx.x > 0) )
+					atomicMax(solver->reinitialize,1);
+				else if((threadIdx.x == blockDim.x - 7 && !(status & 17)) && (blockIdx.x < gridDim.x - 1) )
+					atomicMax(solver->reinitialize,1);
+				else if((threadIdx.y == 6 && !(status & 3)) && (blockIdx.y > 0) )
+					atomicMax(solver->reinitialize,1);
+				else if((threadIdx.y == blockDim.y - 7 && !(status & 5)) && (blockIdx.y < gridDim.y - 1) )
+					atomicMax(solver->reinitialize,1);
+			}
+
+			solver->cudaDofVector2[Entity.getIndex()]  += tau*fu;
+		}
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+#endif
+
+
+
+
+#endif /* TNLNARROWBAND_IMPL_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h b/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb41d572674bd468cfa0286e274e630dd56fdfa6
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h
@@ -0,0 +1,1313 @@
+/***************************************************************************
+                          tnlNarrowBand2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND2D_IMPL_H_
+#define TNLNARROWBAND2D_IMPL_H_
+
+#define NARROWBAND_SUBGRID_SIZE 32
+
+#include "tnlNarrowBand.h"
+
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real  tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return -arg;
+	return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlNarrowBand< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand()
+:dofVector(Mesh)
+{
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	//Entity.refresh();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+	tau = parameters.getParameter< double >( "tau" );
+
+	finalTime = parameters.getParameter< double >( "final-time" );
+
+	statusGridSize = ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaStatusVector),  statusGridSize*statusGridSize*sizeof(int));
+//	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(),  statusGridSize*statusGridSize* sizeof(int)), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&reinitialize, sizeof(int));
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+#endif
+
+	int n = Mesh.getDimensions().x();
+
+	dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocks2(statusGridSize ,statusGridSize);
+	initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+
+	/*dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);*/
+	initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+
+	cout << "Solver initialized." << endl;
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlockFS(1, 512);
+	dim3 numBlocksFS(4,1);
+	dim3 threadsPerBlockNB(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocksNB(n/NARROWBAND_SUBGRID_SIZE + 1,n/NARROWBAND_SUBGRID_SIZE + 1);
+
+	double time = 0.0;
+	int reinit = 0;
+
+	cout << "Hi!" << endl;
+	runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	cout << "Hi2!" << endl;
+	while(time < finalTime)
+	{
+		if(tau+time > finalTime)
+			tau=finalTime-time;
+
+		runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		time += tau;
+
+
+		cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		if(reinit != 0 /*&& time != finalTime */)
+		{
+			cout << time << endl;
+
+			initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+		}
+	}
+
+	//data.setLike(dofVector.getData());
+	//cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	//data.save("u-00001.tnl");
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+	//								8 - to the east of curve, 	16 - to the west of curve.
+	int subgridID = i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);
+	if(/*cudaStatusVector[subgridID] != 0 &&*/ i<Mesh.getDimensions().x() && Mesh.getDimensions().y())
+	{
+		tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+		Entity.setCoordinates(CoordinatesType(i,j));
+		Entity.refresh();
+		tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real a,b, tmp;
+
+		if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9)) */)
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17)) */)
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0/* || (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3)) */)
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5))*/ )
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+		}
+
+
+		if(abs(a-b) >= h)
+			tmp = fabsMin(a,b) + sign(value)*h;
+		else
+			tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	//	cudaDofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+		atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp);
+	}
+
+}
+
+
+__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+
+
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+
+	if(solver->Mesh.getDimensions().x() > gx  && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int i = threadIdx.x + blockDim.x*blockIdx.x;
+	int j = blockDim.y*blockIdx.y + threadIdx.y;
+
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	int gid = Entity.getIndex();
+
+	cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector2[gid]);
+
+	if (i >0 && j > 0 && i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y())
+	{
+		if(cudaDofVector2[gid]*cudaDofVector2[gid+1] <= 0 )
+		{
+			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+			cudaDofVector2[gid+1] = sign(cudaDofVector2[gid+1])*0.5*h;
+		}
+		if( cudaDofVector2[gid]*cudaDofVector2[gid+Mesh.getDimensions().x()] <= 0 )
+		{
+			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+			cudaDofVector2[gid+Mesh.getDimensions().x()] = sign(cudaDofVector2[gid+Mesh.getDimensions().x()])*0.5*h;
+		}
+
+		if(cudaDofVector2[gid]*cudaDofVector2[gid-1] <= 0 )
+		{
+			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+			cudaDofVector2[gid-1] = sign(cudaDofVector2[gid-1])*0.5*h;
+		}
+		if( cudaDofVector2[gid]*cudaDofVector2[gid-Mesh.getDimensions().x()] <= 0 )
+		{
+			cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h;
+			cudaDofVector2[gid-Mesh.getDimensions().x()] = sign(cudaDofVector2[gid-Mesh.getDimensions().x()])*0.5*h;
+		}
+	}
+
+
+//
+
+
+
+
+
+
+//	if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() )
+//	{
+//		if(cudaDofVector[Entity.getIndex()] > 0)
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0001(i,j);
+//					else
+//						setupSquare0000(i,j);
+//				}
+//			}
+//		}
+//
+//	}
+
+	return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	//Real fy = abs(y);
+
+	//Real tmpMin = Min(fx,abs(y));
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+
+	int gx = 0;
+	int gy = threadIdx.y;
+	//if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+	//	return;
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	//int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	//int id1 = gx+gy;
+	//int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+	if(blockIdx.x==0)
+	{
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+
+}
+
+
+
+
+__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	__shared__ double u0;
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+
+//		printf("Hello from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+		if(threadIdx.x+threadIdx.y == 0)
+		{
+//			printf("Hello from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+
+			if(blockIdx.x+blockIdx.y == 0)
+				*(solver->reinitialize) = 0;
+
+			solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] = 0;
+
+			u0 = solver->cudaDofVector2[(blockDim.y*blockIdx.y + 0)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + 0];
+		}
+		__syncthreads();
+
+		double u = solver->cudaDofVector2[(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x];
+
+		if(u*u0 <=0.0)
+			atomicMax(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y]),1);
+	}
+//	if(threadIdx.x+threadIdx.y == 0)
+
+//	printf("Bye from  block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y);
+
+
+}
+
+
+
+// run this with one thread per block
+__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+//	printf("Hello\n");
+	if(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] == 1)
+	{
+//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+//								8 - to the east of curve, 	16 - to the west of curve.
+			if(blockIdx.x > 0)
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x - 1 + gridDim.x*blockIdx.y]), 16);
+
+			if(blockIdx.x < gridDim.x - 1)
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + 1 + gridDim.x*blockIdx.y]), 8);
+
+			if(blockIdx.y > 0 )
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y - 1)]), 4);
+
+			if(blockIdx.y < gridDim.y - 1)
+				atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y + 1)]), 2);
+	}
+
+
+}
+
+
+
+
+
+__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, double tau)
+{
+	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x()+ threadIdx.x;
+	int i = threadIdx.x + blockIdx.x*blockDim.x;
+	int j = threadIdx.y + blockIdx.y*blockDim.y;
+
+//	if(i+j == 0)
+//		printf("Hello\n");
+
+	int blockID = blockIdx.x + blockIdx.y*gridDim.x; /*i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);*/
+
+	int status = solver->cudaStatusVector[blockID];
+
+	if(solver->Mesh.getDimensions().x() > i && solver->Mesh.getDimensions().y() > j)
+	{
+
+//		if(status != 0)
+		{
+			tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh);
+			Entity.setCoordinates(Containers::StaticVector<2,double>(i,j));
+			Entity.refresh();
+			tnlNeighborGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+			double value = solver->cudaDofVector2[Entity.getIndex()];
+			double xf,xb,yf,yb, grad, fu, a,b;
+			a = b = 0.0;
+
+			if( i == 0 /*|| (threadIdx.x == 0 && !(status & 9)) */)
+			{
+				xb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+				xf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+			else if( i == solver->Mesh.getDimensions().x() - 1 /*|| (threadIdx.x == blockDim.x - 1 && !(status & 17)) */)
+			{
+				xb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()] - value;
+			}
+			else
+			{
+				xb =  value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver-> cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+
+			if( j == 0/* || (threadIdx.y == 0 && !(status & 3))*/ )
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] ;
+				yf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			else if( j == solver->Mesh.getDimensions().y() - 1  /*|| (threadIdx.y == blockDim.y - 1 && !(status & 5)) */)
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+				yf = solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()] - value;
+			}
+			else
+			{
+				yb = value - solver->cudaDofVector2[neighborEntities.template getEntityIndex< 0, -1 >()];
+				yf = solver-> cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			__syncthreads();
+
+
+
+
+
+			   if(sign(value) > 0.0)
+			   {
+				   xf = solver->negativePart(xf);
+
+				   xb = solver->positivePart(xb);
+
+				   yf = solver->negativePart(yf);
+
+				   yb = solver->positivePart(yb);
+
+			   }
+			   else
+			   {
+
+				   xb = solver->negativePart(xb);
+
+				   xf = solver->positivePart(xf);
+
+				   yb = solver->negativePart(yb);
+
+				   yf = solver->positivePart(yf);
+			   }
+
+
+			   if(xb > xf)
+				   a = xb*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+			   else
+				   a = xf*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+
+			   if(yb > yf)
+				   b = yb*solver->Mesh.template getSpaceStepsProducts< 0, -1 >();
+			   else
+				   b = yf*solver->Mesh.template getSpaceStepsProducts< 0, -1 >();
+
+
+
+//			grad = sqrt(0.5 * (xf*xf + xb*xb    +   yf*yf + yb*yb ) )*solver->Mesh.template getSpaceStepsProducts< -1, 0 >();
+
+			grad = sqrt(/*0.5 **/ (a*a    +   b*b ) );
+
+			fu = -1.0 * grad;
+
+//			if((tau*fu+value)*value <=0 )
+//			{
+//				//			1 - with curve,  	2 - to the north of curve, 	4  - to the south of curve,
+//				//								8 - to the east of curve, 	16 - to the west of curve.
+//
+//				if((threadIdx.x == 1 && !(status & 9)) && (blockIdx.x > 0) )
+//					atomicMax(solver->reinitialize,1);
+//				else if((threadIdx.x == blockDim.x - 2 && !(status & 17)) && (blockIdx.x < gridDim.x - 1) )
+//					atomicMax(solver->reinitialize,1);
+//				else if((threadIdx.y == 1 && !(status & 3)) && (blockIdx.y > 0) )
+//					atomicMax(solver->reinitialize,1);
+//				else if((threadIdx.y == blockDim.y - 2 && !(status & 5)) && (blockIdx.y < gridDim.y - 1) )
+//					atomicMax(solver->reinitialize,1);
+//			}
+
+			solver->cudaDofVector2[Entity.getIndex()]  += tau*fu;
+		}
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+#endif
+
+
+
+
+#endif /* TNLNARROWBAND_IMPL_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand2D_impl.h b/examples/narrow-band/tnlNarrowBand2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1afb9ab8f7d12f1639d5a08d64edf8143f47083
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand2D_impl.h
@@ -0,0 +1,927 @@
+/***************************************************************************
+                          tnlNarrowBand2D_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND2D_IMPL_H_
+#define TNLNARROWBAND2D_IMPL_H_
+
+#include "tnlNarrowBand.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlNarrowBand< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand()
+:Entity(Mesh),
+ dofVector(Mesh),
+ dofVector2(Mesh)
+{
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+	dofVector2.load(initialCondition);
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	Entity.refresh();
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+	cout << "a" << endl;
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++)
+	{
+		dofVector2[i]=INT_MAX*sign(dofVector[i]);
+	}
+
+	for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++)
+	{
+		for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++)
+			{
+			this->Entity.setCoordinates(CoordinatesType(i,j));
+			this->Entity.refresh();
+			neighborEntities.refresh(Mesh,Entity.getIndex());
+
+				if(dofVector[this->Entity.getIndex()] > 0)
+				{
+					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1111(i,j);
+							else
+								setupSquare1110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1101(i,j);
+							else
+								setupSquare1100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1011(i,j);
+							else
+								setupSquare1010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1001(i,j);
+							else
+								setupSquare1000(i,j);
+						}
+					}
+				}
+				else
+				{
+					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0111(i,j);
+							else
+								setupSquare0110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0101(i,j);
+							else
+								setupSquare0100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0011(i,j);
+							else
+								setupSquare0010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0001(i,j);
+							else
+								setupSquare0000(i,j);
+						}
+					}
+				}
+
+			}
+	}
+	cout << "a" << endl;
+
+//	Real tmp = 0.0;
+//	Real ax=0.5/sqrt(2.0);
+//
+//	if(!exactInput)
+//	{
+//		for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++)
+//				dofVector[i]=0.5*h*sign(dofVector[i]);
+//	}
+//
+//
+//	for(Index i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		for(Index j = 1; j < Mesh.getDimensions().y()-1; j++)
+//		{
+//			 tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//			if(tmp == 0.0)
+//			{}
+//			else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//			{}
+//			else
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//		}
+//	}
+//
+//
+//
+//	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		Index j = 0;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+//	{
+//		Index i = 0;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+//	{
+//		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//
+//	Index i = Mesh.getDimensions().x() - 1;
+//	Index j = Mesh.getDimensions().y() - 1;
+//
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	j = 0;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	i = 0;
+//	j = Mesh.getDimensions().y() -1;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	j = 0;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+	//data.setLike(dofVector2.getData());
+	//data=dofVector2.getData();
+	//cout << data.getType() << endl;
+	dofVector2.save("u-00000.tnl");
+	//dofVector2.getData().save("u-00000.tnl");
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+//	data.setLike(dofVector2.getData());
+//	data = dofVector2.getData();
+//	cout << data.getType() << endl;
+	dofVector2.save("u-00001.tnl");
+	//dofVector2.getData().save("u-00001.tnl");
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+				 dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+	}
+
+
+	if(fabs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+
+	dofVector2[Entity.getIndex()] = fabsMin(value, tmp);
+
+//	if(dofVector2[Entity.getIndex()] > 1.0)
+//		cout << value << "    " << tmp << " " << dofVector2[Entity.getIndex()] << endl;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+
+
+
+
+#endif /* TNLNARROWBAND_IMPL_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h b/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b96ad58205d0578776b2b2d645eb71292c0fad4
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h
@@ -0,0 +1,961 @@
+/***************************************************************************
+                          tnlNarrowBand2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND3D_IMPL_H_
+#define TNLNARROWBAND3D_IMPL_H_
+
+#include "tnlNarrowBand.h"
+
+//__device__
+//double fabsMin( double x, double y)
+//{
+//	double fx = abs(x);
+//
+//	if(Min(fx,abs(y)) == fx)
+//		return x;
+//	else
+//		return y;
+//}
+//
+//__device__
+//double atomicFabsMin(double* address, double val)
+//{
+//	unsigned long long int* address_as_ull =
+//						  (unsigned long long int*)address;
+//	unsigned long long int old = *address_as_ull, assumed;
+//	do {
+//		assumed = old;
+//			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) ));
+//	} while (assumed != old);
+//	return __longlong_as_double(old);
+//}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlNarrowBand< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	this->h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(8, 8,8);
+	dim3 numBlocks(n/8 + 1, n/8 +1, n/8 +1);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(1, 512);
+	dim3 numBlocks(8,1);
+
+
+	runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k)
+{
+	tnlGridEntity< tnlGrid< 3,double, TNL::Devices::Host, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1,  0 >()] );
+	}
+
+	if( k == 0 )
+		c = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+	else
+	{
+		c = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  1 >()] );
+	}
+
+	Real hD = 3.0*h*h - 2.0*(a*a + b*b + c*c - a*b - a*c - b*c);
+
+	if(hD < 0.0)
+		tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h;
+	else
+		tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) );
+
+	atomicFabsMin(&cudaDofVector2[Entity.getIndex()],tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid(int i, int j, int k)
+{
+	tnlGridEntity< tnlGrid< 3,double, TNL::Devices::Host, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	int gid = Entity.getIndex();
+
+	if(abs(cudaDofVector[gid]) < 1.8*h)
+		cudaDofVector2[gid] = cudaDofVector[gid];
+	else
+		cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]);
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlNarrowBand< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+	int gx = 0;
+	int gy = threadIdx.y;
+
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+
+	if(blockIdx.x==0)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx = 0;
+		gy = threadIdx.y;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+
+
+
+
+	else if(blockIdx.x==4)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx = 0;
+		gy = threadIdx.y;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==5)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==6)
+	{
+
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==7)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlNarrowBand< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gz = blockDim.z*blockIdx.z + threadIdx.z;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && solver->Mesh.getDimensions().z() > gz)
+	{
+		solver->initGrid(gx,gy,gz);
+	}
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(INT_MAX,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(-INT_MAX,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-al;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//
+//
+//
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-al;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//}
+#endif
+
+
+
+
+#endif /* TNLNARROWBAND_IMPL_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand3D_impl.h b/examples/narrow-band/tnlNarrowBand3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..33d7ef8cd2c3a19992760ed15dc732b6da7f42d8
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand3D_impl.h
@@ -0,0 +1,307 @@
+/***************************************************************************
+                          tnlNarrowBand2D_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND3D_IMPL_H_
+#define TNLNARROWBAND3D_IMPL_H_
+
+#include "tnlNarrowBand.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlNarrowBand< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand()
+:Entity(Mesh),
+ dofVector(Mesh),
+ dofVector2(Mesh)
+{
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+	dofVector2.load(initialCondition);
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	Entity.refresh();
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+//	cout << "bla "<<endl;
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().y()*Mesh.getDimensions().z();i++)
+	{
+
+		if (abs(dofVector[i]) < 1.8*h)
+			dofVector2[i]=dofVector[i];
+		else
+			dofVector2[i]=INT_MAX*sign(dofVector[i]);
+	}
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+	dofVector2.save("u-00001.tnl");
+
+	cout << "bla 3"<<endl;
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j,k));
+	this->Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighborEntities.template getEntityIndex< 1,  0,  0>()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighborEntities.template getEntityIndex< -1,  0,  0>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 1,  0,  0>()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  1,  0>()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0>()];
+	else
+	{
+		b = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  1,  0>()] );
+	}
+
+	if( k == 0 )
+		c = dofVector2[neighborEntities.template getEntityIndex< 0,  0,  1>()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = dofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1>()];
+	else
+	{
+		c = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  0,  1>()] );
+	}
+
+	Real hD = 3.0*h*h - 2.0*(a*a+b*b+c*c-a*b-a*c-b*c);
+
+	if(hD < 0.0)
+		tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h;
+	else
+		tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) );
+
+
+	dofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+}
+
+
+
+#endif /* TNLNARROWBAND_IMPL_H_ */
diff --git a/examples/narrow-band/tnlNarrowBand_CUDA.h b/examples/narrow-band/tnlNarrowBand_CUDA.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca9b1da2cc6e26b14bc003532b6eea75e89d907d
--- /dev/null
+++ b/examples/narrow-band/tnlNarrowBand_CUDA.h
@@ -0,0 +1,203 @@
+/***************************************************************************
+                          tnlNarrowBand_CUDA.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLNARROWBAND_H_
+#define TNLNARROWBAND_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+
+#include <functions/tnlMeshFunction.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlNarrowBand
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlNarrowBand();
+
+        static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+	bool run();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType negativePart(const RealType arg) const;
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid();
+	__device__ void updateValue(const Index i, const Index j);
+	__device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	int* cudaStatusVector;
+	int counter;
+	int* reinitialize;
+	__device__ void setupSquare1000(Index i, Index j);
+	__device__ void setupSquare1100(Index i, Index j);
+	__device__ void setupSquare1010(Index i, Index j);
+	__device__ void setupSquare1001(Index i, Index j);
+	__device__ void setupSquare1110(Index i, Index j);
+	__device__ void setupSquare1101(Index i, Index j);
+	__device__ void setupSquare1011(Index i, Index j);
+	__device__ void setupSquare1111(Index i, Index j);
+	__device__ void setupSquare0000(Index i, Index j);
+	__device__ void setupSquare0100(Index i, Index j);
+	__device__ void setupSquare0010(Index i, Index j);
+	__device__ void setupSquare0001(Index i, Index j);
+	__device__ void setupSquare0110(Index i, Index j);
+	__device__ void setupSquare0101(Index i, Index j);
+	__device__ void setupSquare0011(Index i, Index j);
+	__device__ void setupSquare0111(Index i, Index j);
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+	int statusGridSize;
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data;
+
+
+	RealType h, tau, finalTime;
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+	bool run();
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid(int i, int j, int k);
+	__device__ void updateValue(const Index i, const Index j, const Index k);
+	__device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	int counter;
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data;
+
+	RealType h;
+
+
+};
+
+
+
+
+
+
+
+#ifdef HAVE_CUDA
+//template<int sweep_t>
+__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i);
+//__global__ void runCUDA(tnlNarrowBand< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+
+__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+__global__ void initSetupGrid1_2CUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, double tau);
+//__global__ void initCUDA(tnlNarrowBand< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver);
+#endif
+
+
+
+#include "tnlNarrowBand2D_CUDA_v4_impl.h"
+//											#include "tnlNarrowBand3D_CUDA_impl.h"
+
+#endif /* TNLNARROWBAND_H_ */
diff --git a/examples/navier-stokes/CMakeLists.txt b/examples/navier-stokes/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/examples/navier-stokes/navierStokesBoundaryConditions_impl.h b/examples/navier-stokes/navierStokesBoundaryConditions_impl.h
index c6674391bc24cd313f78b6c703c6d786d91a181f..3eb66e8555419614e134d0dc6370461336dc3301 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 Config::ParameterContainer& 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;
diff --git a/examples/navier-stokes/navierStokesSolver.h b/examples/navier-stokes/navierStokesSolver.h
index efdc431a7885e4078b6199e94894407fc374898b..5e05a75aeec5e2bc788ee305cbb1ad3a48a91ea7 100644
--- a/examples/navier-stokes/navierStokesSolver.h
+++ b/examples/navier-stokes/navierStokesSolver.h
@@ -93,7 +93,7 @@ class navierStokesSolver
 
    bool solve();
 
-   void GetExplicitRHS( const RealType& time,
+   void getExplicitUpdate( const RealType& time,
                         const RealType& tau,
                         DofVectorType& _u,
                         DofVectorType& _fu );
diff --git a/examples/navier-stokes/navierStokesSolverMonitor_impl.h b/examples/navier-stokes/navierStokesSolverMonitor_impl.h
index 47e82e3bba940c430b5d16e377a6c1751a96b808..462d31257aabda14745385f13bb70a412b90c6ce 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
    {
      std::cout << "V=( " << uMax
            << " , " << uAvg
diff --git a/examples/navier-stokes/navierStokesSolver_impl.h b/examples/navier-stokes/navierStokesSolver_impl.h
index 8fa92c2cc1624ea6ca167ee8475ff53ddd980208..b1f607475c396f4905909474b0f2bf7324eea2ee 100644
--- a/examples/navier-stokes/navierStokesSolver_impl.h
+++ b/examples/navier-stokes/navierStokesSolver_impl.h
@@ -260,12 +260,12 @@ bool navierStokesSolver< Mesh, EulerScheme > :: makeSnapshot( const RealType& t,
 }
 
 template< typename Mesh, typename EulerScheme >
-void navierStokesSolver< Mesh, EulerScheme > :: GetExplicitRHS(  const RealType& time,
+void navierStokesSolver< Mesh, EulerScheme > :: getExplicitUpdate(  const RealType& time,
                                                                  const RealType& tau,
                                                                  DofVectorType& u,
                                                                  DofVectorType& fu )
 {
-   nsSolver.getExplicitRhs( time, tau, u, fu );
+   nsSolver.getExplicitUpdate( time, tau, u, fu );
    solverMonitor.uMax = this->mesh.getAbsMax( nsSolver.getU() );
    solverMonitor.uAvg = this->mesh.getLpNorm( nsSolver.getU(), 1.0 );
    solverMonitor.eMax = this->mesh.getAbsMax( nsSolver.getEnergy() );
diff --git a/examples/navier-stokes/share/CMakeLists.txt b/examples/navier-stokes/share/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/examples/navier-stokes/share/examples/CMakeLists.txt b/examples/navier-stokes/share/examples/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/examples/quad-test/main.cpp b/examples/quad-test/main.cpp
index dbaf0114448391b9c80744882e9fe7cb86ab4cca..583d3c4ca8470297d320ec305a99e96f6ef547d7 100644
--- a/examples/quad-test/main.cpp
+++ b/examples/quad-test/main.cpp
@@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {
 
 	String inputFile = parameters.getParameter <String> ("input-file");
 	File binaryFile;
-	if(! binaryFile.open(inputFile, tnlReadMode)) {
+	if(! binaryFile.open(inputFile, IOMode::read)) {
 		cerr << "I am not able to open the file " << inputFile << "." << std::endl;
 		return 1;
 	}
@@ -48,4 +48,4 @@ int main(int argc, char* argv[]) {
 	CSR <QuadDouble> quadMatrix("quad");
 	quadMatrix = doubleMatrix;
 	return EXIT_SUCCESS;
-}
\ No newline at end of file
+}
diff --git a/examples/transport-equation/CMakeLists.txt b/examples/transport-equation/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c4b587d180a06142149459094b3ca2e8c3e9150
--- /dev/null
+++ b/examples/transport-equation/CMakeLists.txt
@@ -0,0 +1,34 @@
+set( tnl_transport_equation_SOURCES     
+     tnl-transport-equation.cpp
+     tnl-transport-equation.cu )
+
+set( tnl_transport_equation_HEADERS
+     tnl-transport-equation.h
+     transportEquationBuildConfigTag.h
+     transportEquationProblem.h
+     transportEquationProblem_impl.h )
+     
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnl-transport-equation${debugExt} tnl-transport-equation.cu)   
+   target_link_libraries( tnl-transport-equation${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+   CUDA_ADD_EXECUTABLE( tnl-transport-equation-eoc${debugExt} tnl-transport-equation-eoc.cu)   
+   target_link_libraries( tnl-transport-equation-eoc${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE( tnl-transport-equation${debugExt} tnl-transport-equation.cpp)     
+   target_link_libraries( tnl-transport-equation${debugExt} tnl${debugExt}-${tnlVersion} )
+   ADD_EXECUTABLE( tnl-transport-equation-eoc${debugExt} tnl-transport-equation-eoc.cpp)     
+   target_link_libraries( tnl-transport-equation-eoc${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+INSTALL( TARGETS tnl-transport-equation${debugExt}
+                 tnl-transport-equation-eoc${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES tnl-run-transport-equation
+               ${tnl_transport_equation_SOURCES}
+               ${tnl_transport_equation_HEADERS}
+         DESTINATION share/tnl-${tnlVersion}/examples/transport-equation )
diff --git a/examples/transport-equation/tnl-run-transport-equation b/examples/transport-equation/tnl-run-transport-equation
new file mode 100644
index 0000000000000000000000000000000000000000..aa33723a4336b7c947c448e6486a2e324ef4edc7
--- /dev/null
+++ b/examples/transport-equation/tnl-run-transport-equation
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-x 0.0 \
+               --proportions-x 1.0 \
+               --proportions-y 1.0 \
+               --size-x 100 \
+               --size-y 100 
+ 
+tnl-init --test-function heaviside-of-vector-norm \
+         --output-file init.tnl \
+         --coefficient -1.0 \
+         --vector-norm-center-0 0.5 \
+         --vector-norm-center-1 0.5 \
+         --vector-norm-center-2 0.5 \
+         --vector-norm-radius 0.2 \
+         --vector-norm-power 0.6 \
+         --vector-norm-max-norm false
+
+tnl-transport-equation --device host \
+                       --initial-condition init.tnl \
+                       --time-discretisation explicit \
+                       --time-step 1.0e-5 \
+                       --boundary-conditions-constant 0.0 \
+                       --discrete-solver euler \
+                       --snapshot-period 0.005 \
+                       --final-time 0.1 \
+                       --numerical-viscosity 1.0 \
+                       --velocity-field-0-constant 1.0 \
+                       --velocity-field-1-constant 1.0 \
+                       --velocity-field-2-constant 1.0
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/transport-equation/tnl-run-transport-equation-eoc b/examples/transport-equation/tnl-run-transport-equation-eoc
new file mode 100755
index 0000000000000000000000000000000000000000..ec08d44172fdb38be9d9349013871fce7e6a6abf
--- /dev/null
+++ b/examples/transport-equation/tnl-run-transport-equation-eoc
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-x 0.0 \
+               --proportions-x 1.0 \
+               --proportions-y 1.0 \
+               --size-x 100 \
+               --size-y 100 
+ 
+tnl-transport-equation-eoc --device host \
+                           --initial-condition heaviside-vector-norm \
+                           --heaviside-multiplicator 1.0 \
+                           --vector-norm-multiplicator -1.0 \
+                           --vector-norm-center-0 0.5 \
+                           --vector-norm-center-1 0.5 \
+                           --vector-norm-center-2 0.5 \
+                           --vector-norm-radius 0.2 \
+                           --vector-norm-power 0.6 \
+                           --vector-norm-max-norm false \
+                           --time-discretisation explicit \
+                           --time-step 1.0e-5 \
+                           --boundary-conditions-constant 0.0 \
+                           --discrete-solver euler \
+                           --snapshot-period 0.005 \
+                           --final-time 0.1 \
+                           --numerical-viscosity 1.0 \
+                           --velocity-field-0-constant 1.0 \
+                           --velocity-field-1-constant 1.0 \
+                           --velocity-field-2-constant 1.0
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/transport-equation/tnl-transport-equation-eoc.cpp b/examples/transport-equation/tnl-transport-equation-eoc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..00e2e867a1c34e3a71073144e0209f15cba9c150
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation-eoc.cpp
@@ -0,0 +1,11 @@
+/***************************************************************************
+                          tnl-transport-equation-eoc.cpp  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#include "tnl-transport-equation-eoc.h"
diff --git a/examples/transport-equation/tnl-transport-equation-eoc.cu b/examples/transport-equation/tnl-transport-equation-eoc.cu
new file mode 100644
index 0000000000000000000000000000000000000000..9a17dc4e1f6297eb2c1ec04dca8dc67535c8a762
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation-eoc.cu
@@ -0,0 +1,12 @@
+/***************************************************************************
+                          tnl-transport-equation-eoc.cu  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#include "tnl-transport-equation-eoc.h"
diff --git a/examples/transport-equation/tnl-transport-equation-eoc.h b/examples/transport-equation/tnl-transport-equation-eoc.h
new file mode 100644
index 0000000000000000000000000000000000000000..98a38425290f06eef37fd6606a2619fb898c6908
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation-eoc.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+                          tnl-transport-equation-eoc.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#include <TNL/tnlConfig.h>
+#include <TNL/Solvers/Solver.h>
+#include <TNL/Solvers/BuildConfigTags.h>
+#include <TNL/Operators/DirichletBoundaryConditions.h>
+#include <TNL/Operators/NeumannBoundaryConditions.h>
+#include <TNL/Operators/Advection/LaxFridrichs.h>
+#include <TNL/Functions/Analytic/Constant.h>
+#include <TNL/Functions/Analytic/VectorNorm.h>
+#include <TNL/Operators/Analytic/Heaviside.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/Meshes/Grid.h>
+#include "transportEquationProblemEoc.h"
+#include "transportEquationBuildConfigTag.h"
+
+using namespace TNL;
+
+typedef transportEquationBuildConfigTag BuildConfig;
+
+/****
+ * Uncomment 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,
+ * especially 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( Config::ConfigDescription& config )
+      {
+         config.addDelimiter( "Transport equation settings:" );
+         config.addDelimiter( "Initial condition" );
+         config.addEntry< String >( "initial-condition", "Set type of initial condition.", "heaviside-vector-norm" );
+            config.addEntryEnum< String >( "heaviside-vector-norm" );
+         Functions::Analytic::VectorNorm< 3, double >::configSetup( config, "vector-norm-" );
+         Operators::Analytic::Heaviside< 3, double >::configSetup( config, "heaviside-" );
+         Operators::Analytic::Shift< 3, double >::configSetup( config, "heaviside-" );
+            
+         config.addDelimiter( "Velocity field" );
+         config.addEntry< String >( "velocity-field", "Type of velocity field.", "constant" );
+            config.addEntryEnum< String >( "constant" );
+         Functions::VectorField< 3, Functions::Analytic::Constant< 3 > >::configSetup( config, "velocity-field-" );
+         
+         config.addDelimiter( "Numerical scheme" );
+         typedef Meshes::Grid< 3 > MeshType;
+         Operators::Advection::LaxFridrichs< MeshType >::configSetup( config );
+         
+         config.addDelimiter( "Boundary conditions" );
+         config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< String >( "dirichlet" );
+            config.addEntryEnum< String >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions.", 0.0 );
+      }
+};
+
+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 const int Dimensions = MeshType::getMeshDimension();
+      
+      template< typename Problem >
+      static bool callSolverStarter( const Config::ParameterContainer& parameters )
+      {
+         SolverStarter solverStarter;
+         return solverStarter.template run< Problem >( parameters );
+      }
+      
+      template< typename DifferentialOperatorType >
+      static bool setBoundaryConditionsType( const Config::ParameterContainer& parameters )
+      {
+         typedef Functions::Analytic::Constant< Dimensions, Real > ConstantFunctionType;
+         String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
+         if( boundaryConditionsType == "dirichlet" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblemEoc< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         if( boundaryConditionsType == "neumann" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblemEoc< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         std::cerr << "Unknown boundary conditions type: " << boundaryConditionsType << "." << std::endl;
+         return false;
+      }
+      
+      template< typename VelocityFieldType >
+      static bool setDifferentialOperatorType( const Config::ParameterContainer& parameters )
+      {
+         typedef Operators::Advection::LaxFridrichs< MeshType, Real, Index, VelocityFieldType > DifferentialOperatorType;
+         return setBoundaryConditionsType< DifferentialOperatorType >( parameters );
+      }
+      
+      static bool setVelocityFieldType( const Config::ParameterContainer& parameters )
+      {
+         String velocityFieldType = parameters.getParameter< String >( "velocity-field" );
+         if( velocityFieldType == "constant" )
+         {
+            typedef Functions::Analytic::Constant< Dimensions, RealType > VelocityFieldType;
+            return setDifferentialOperatorType< VelocityFieldType >( parameters );
+         }
+         return false;
+      }
+
+      static bool run( const Config::ParameterContainer& parameters )
+      {
+         return setVelocityFieldType( parameters );
+      }      
+};
+
+int main( int argc, char* argv[] )
+{
+   Solvers::Solver< advectionSetter, advectionConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/src/UnitTests/Containers/StaticArrayTest.cu b/examples/transport-equation/tnl-transport-equation.cpp
similarity index 60%
rename from src/UnitTests/Containers/StaticArrayTest.cu
rename to examples/transport-equation/tnl-transport-equation.cpp
index 00fa118fd23a8e5898f6c8736172cc3a70a4fe46..f8cc396d31d0592dc8626c370015886f1d3b2dc4 100644
--- a/src/UnitTests/Containers/StaticArrayTest.cu
+++ b/examples/transport-equation/tnl-transport-equation.cpp
@@ -1,12 +1,11 @@
 /***************************************************************************
-                          StaticArrayTest.cu  -  description
+                          tnl-transport-equation.cpp  -  description
                              -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "StaticArrayTest.h"
-
+#include "tnl-transport-equation.h"
diff --git a/src/UnitTests/Containers/StaticVectorTest.cu b/examples/transport-equation/tnl-transport-equation.cu
similarity index 60%
rename from src/UnitTests/Containers/StaticVectorTest.cu
rename to examples/transport-equation/tnl-transport-equation.cu
index 693ace5c43590a06a2f8c7c087a0d1480a35d02a..068984a891fdc9df2c58ad24ae7a5c9b87ef015d 100644
--- a/src/UnitTests/Containers/StaticVectorTest.cu
+++ b/examples/transport-equation/tnl-transport-equation.cu
@@ -1,11 +1,11 @@
 /***************************************************************************
-                          StaticVectorTest.cu  -  description
+                          tnl-transport-equation.cu  -  description
                              -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "StaticVectorTest.h"
+#include "tnl-transport-equation.h"
diff --git a/examples/transport-equation/tnl-transport-equation.h b/examples/transport-equation/tnl-transport-equation.h
new file mode 100644
index 0000000000000000000000000000000000000000..be0083153b91c87142888d4a5174c331f06b8e8b
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation.h
@@ -0,0 +1,132 @@
+/***************************************************************************
+                          tnl-transport-equation.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#include <TNL/tnlConfig.h>
+#include <TNL/Solvers/Solver.h>
+#include <TNL/Solvers/BuildConfigTags.h>
+#include <TNL/Operators/DirichletBoundaryConditions.h>
+#include <TNL/Operators/NeumannBoundaryConditions.h>
+#include <TNL/Operators/Advection/LaxFridrichs.h>
+#include <TNL/Functions/Analytic/Constant.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/Meshes/Grid.h>
+#include "transportEquationProblem.h"
+#include "transportEquationBuildConfigTag.h"
+
+using namespace TNL;
+
+typedef transportEquationBuildConfigTag BuildConfig;
+
+/****
+ * Uncomment 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,
+ * especially 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( Config::ConfigDescription& config )
+      {
+         config.addDelimiter( "Transport equation settings:" );
+         config.addEntry< String >( "velocity-field", "Type of velocity field.", "constant" );
+            config.addEntryEnum< String >( "constant" );
+         Functions::VectorField< 3, Functions::Analytic::Constant< 3 > >::configSetup( config, "velocity-field-" );
+         
+         typedef Meshes::Grid< 3 > MeshType;
+         Operators::Advection::LaxFridrichs< MeshType >::configSetup( config );
+         
+         config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< String >( "dirichlet" );
+            config.addEntryEnum< String >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+      }
+};
+
+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 const int Dimensions = MeshType::getMeshDimension();
+      
+      template< typename Problem >
+      static bool callSolverStarter( const Config::ParameterContainer& parameters )
+      {
+         SolverStarter solverStarter;
+         return solverStarter.template run< Problem >( parameters );
+      }
+      
+      template< typename DifferentialOperatorType >
+      static bool setBoundaryConditionsType( const Config::ParameterContainer& parameters )
+      {
+         typedef Functions::Analytic::Constant< Dimensions, Real > ConstantFunctionType;
+         String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
+         if( boundaryConditionsType == "dirichlet" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblem< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         if( boundaryConditionsType == "neumann" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblem< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         std::cerr << "Unknown boundary conditions type: " << boundaryConditionsType << "." << std::endl;
+         return false;
+      }
+      
+      template< typename VelocityFieldType >
+      static bool setDifferentialOperatorType( const Config::ParameterContainer& parameters )
+      {
+         typedef Operators::Advection::LaxFridrichs< MeshType, Real, Index, VelocityFieldType > DifferentialOperatorType;
+         return setBoundaryConditionsType< DifferentialOperatorType >( parameters );
+      }
+      
+      static bool setVelocityFieldType( const Config::ParameterContainer& parameters )
+      {
+         String velocityFieldType = parameters.getParameter< String >( "velocity-field" );
+         if( velocityFieldType == "constant" )
+         {
+            typedef Functions::Analytic::Constant< Dimensions, RealType > VelocityFieldType;
+            return setDifferentialOperatorType< VelocityFieldType >( parameters );
+         }
+         return false;
+      }
+
+      static bool run( const Config::ParameterContainer& parameters )
+      {
+         return setVelocityFieldType( parameters );
+      }      
+};
+
+int main( int argc, char* argv[] )
+{
+   Solvers::Solver< advectionSetter, advectionConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/examples/transport-equation/transportEquationBuildConfigTag.h b/examples/transport-equation/transportEquationBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..884060fa2d973530f1b5fb926ee280aa11a4b7ed
--- /dev/null
+++ b/examples/transport-equation/transportEquationBuildConfigTag.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+                          transportEquationBuildConfigTag.cpp  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Solvers/BuildConfigTags.h>
+
+namespace TNL {
+
+class transportEquationBuildConfigTag{};
+
+namespace Solvers {
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct ConfigTagReal< transportEquationBuildConfigTag, float > { enum { enabled = false }; };
+template<> struct ConfigTagReal< transportEquationBuildConfigTag, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct ConfigTagIndex< transportEquationBuildConfigTag, short int >{ enum { enabled = false }; };
+template<> struct ConfigTagIndex< transportEquationBuildConfigTag, long int >{ enum { enabled = false }; };
+
+/****
+ * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+
+template< int Dimensions, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< transportEquationBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
+      { enum { enabled = ConfigTagDimension< transportEquationBuildConfigTag, Dimensions >::enabled  &&
+                         ConfigTagReal< transportEquationBuildConfigTag, Real >::enabled &&
+                         ConfigTagDevice< transportEquationBuildConfigTag, Device >::enabled &&
+                         ConfigTagIndex< transportEquationBuildConfigTag, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct ConfigTagExplicitSolver< transportEquationBuildConfigTag, Solvers::ExplicitEulerSolverTag >{ enum { enabled = true }; };
+
+} // namespace Solvers
+} // namespace TNL
diff --git a/examples/advection/advectionProblem.h b/examples/transport-equation/transportEquationProblem.h
similarity index 72%
rename from examples/advection/advectionProblem.h
rename to examples/transport-equation/transportEquationProblem.h
index 0dbae12e6d5513e3546632eb5ea44922f9a1df24..04bbd1bdd4bafeffe66bc56c1bfda7ca4d005940 100644
--- a/examples/advection/advectionProblem.h
+++ b/examples/transport-equation/transportEquationProblem.h
@@ -1,5 +1,14 @@
-#ifndef advectionPROBLEM_H_
-#define advectionPROBLEM_H_
+/***************************************************************************
+                          transportEquationProblem.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
 
 #include <TNL/Problems/PDEProblem.h>
 #include <TNL/Functions/MeshFunction.h>
@@ -12,12 +21,12 @@ namespace TNL {
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-           typename DifferentialOperator >
-class advectionProblem:
-   public PDEProblem< Mesh,
-                         typename DifferentialOperator::RealType,
-                         typename Mesh::DeviceType,
-                         typename DifferentialOperator::IndexType >
+          typename DifferentialOperator >
+class transportEquationProblem:
+public PDEProblem< Mesh,
+                   typename DifferentialOperator::RealType,
+                   typename Mesh::DeviceType,
+                   typename DifferentialOperator::IndexType >
 {
    public:
 
@@ -30,7 +39,9 @@ class advectionProblem:
       typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer;
       typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer;
       typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
-      
+      typedef typename DifferentialOperator::VelocityFieldType VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer;
+
       using typename BaseType::MeshType;
       using typename BaseType::MeshPointer;
       using typename BaseType::DofVectorType;
@@ -76,7 +87,7 @@ class advectionProblem:
       void bindDofs( const MeshPointer& mesh,
                      DofVectorPointer& dofs );
 
-      void getExplicitRHS( const RealType& time,
+      void getExplicitUpdate( const RealType& time,
                            const RealType& tau,
                            const MeshPointer& mesh,
                            DofVectorPointer& _u,
@@ -92,6 +103,11 @@ class advectionProblem:
                                  DofVectorPointer& rightHandSide,
                                  MeshDependentDataPointer& meshDependentData );
 
+      template< typename Matrix >
+      void saveFailedLinearSystem( const Matrix& matrix,
+                                   const DofVectorType& dofs,
+                                   const DofVectorType& rightHandSide ) const;
+
    protected:
 
       MeshFunctionPointer uPointer, velocityX, velocityY, velocityZ;
@@ -100,13 +116,11 @@ class advectionProblem:
 
       BoundaryConditionPointer boundaryConditionPointer;
 
-      RightHandSidePointer rightHandSidePointer;      
+      RightHandSidePointer rightHandSidePointer;
       
-      String velocityType;
+      VelocityFieldPointer velocityField;
 };
 
 } // namespace TNL
 
-#include "advectionProblem_impl.h"
-
-#endif /* advectionPROBLEM_H_ */
+#include "transportEquationProblem_impl.h"
diff --git a/examples/inviscid-flow/1d/eulerProblem.h b/examples/transport-equation/transportEquationProblemEoc.h
similarity index 50%
rename from examples/inviscid-flow/1d/eulerProblem.h
rename to examples/transport-equation/transportEquationProblemEoc.h
index f687ee5460accc7a593bb8f6e034872f8d8e6eda..cd851bd3005ea5eac669ad6779f56fdccb9dbe11 100644
--- a/examples/inviscid-flow/1d/eulerProblem.h
+++ b/examples/transport-equation/transportEquationProblemEoc.h
@@ -1,21 +1,30 @@
-#ifndef eulerPROBLEM_H_
-#define eulerPROBLEM_H_
+/***************************************************************************
+                          transportEquationProblemEoc.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
 
 #include <TNL/Problems/PDEProblem.h>
 #include <TNL/Functions/MeshFunction.h>
+#include <TNL/SharedPointer.h>
+#include "transportEquationProblem.h"
 
 using namespace TNL::Problems;
+
 namespace TNL {
 
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-           typename DifferentialOperator >
-class eulerProblem:
-   public PDEProblem< Mesh,
-                         typename DifferentialOperator::RealType,
-                         typename Mesh::DeviceType,
-                         typename DifferentialOperator::IndexType >
+          typename DifferentialOperator >
+class transportEquationProblemEoc:
+public transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >
 {
    public:
 
@@ -23,44 +32,38 @@ class eulerProblem:
       typedef typename Mesh::DeviceType DeviceType;
       typedef typename DifferentialOperator::IndexType IndexType;
       typedef Functions::MeshFunction< Mesh > MeshFunctionType;
+      typedef transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator > BaseType;
       typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer;
       typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer;
       typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer;
       typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
-      typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;      
+      typedef typename DifferentialOperator::VelocityFieldType VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer;
       
+
       using typename BaseType::MeshType;
       using typename BaseType::MeshPointer;
       using typename BaseType::DofVectorType;
       using typename BaseType::DofVectorPointer;
       using typename BaseType::MeshDependentDataType;
-      using typename BaseType::MeshDependentDataPointer;
-
-      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;
+      using typename BaseType::MeshDependentDataPointer; 
+      
+      //using BaseType::getExplicitUpdate;
       
-
-
       static String getTypeStatic();
 
       String getPrologHeader() const;
 
-      void writeProlog( Logger& logger,
-                        const Config::ParameterContainer& parameters ) const;
-
-      bool setup( const MeshPointer& meshPointer, 
+      bool setup( const MeshPointer& meshPointer,
                   const Config::ParameterContainer& parameters,
-                  const String& prefix );
+                  const String& prefix = "" );
 
       bool setInitialCondition( const Config::ParameterContainer& parameters,
                                 const MeshPointer& mesh,
                                 DofVectorPointer& dofs,
                                 MeshDependentDataPointer& meshDependentData );
 
-      template< typename Matrix >
+      /*template< typename Matrix >
       bool setupLinearSystem( const MeshPointer& mesh,
                               Matrix& matrix );
 
@@ -75,46 +78,18 @@ class eulerProblem:
       void bindDofs( const MeshPointer& mesh,
                      DofVectorPointer& dofs );
 
-      void getExplicitRHS( const RealType& time,
+      void getExplicitUpdate( const RealType& time,
                            const RealType& tau,
                            const MeshPointer& mesh,
                            DofVectorPointer& _u,
                            DofVectorPointer& _fu,
-                           MeshDependentDataPointer& meshDependentData );
-
-      template< typename Matrix >
-      void assemblyLinearSystem( const RealType& time,
-                                 const RealType& tau,
-                                 const MeshPointer& mesh,
-                                 DofVectorPointer& dofs,
-                                 Matrix& matrix,
-                                 DofVectorPointer& rightHandSide,
-                                 MeshDependentDataPointer& meshDependentData );
-      
-      bool postIterate( const RealType& time,
-                        const RealType& tau,
-                        const MeshPointer& mesh,
-                        DofVectorPointer& dofs,
-                        MeshDependentDataPointer& meshDependentData );
-
-   protected:
-
-      DifferentialOperatorPointer differentialOperatorPointer;
-      BoundaryConditionPointer boundaryConditionsPointer;
-      RightHandSidePointer rightHandSidePointer;
-      
-      MeshFunctionPointer uRho, uRhoVelocity, uEnergy;
-      MeshFunctionPointer fuRho, fuRhoVelocity, fuEnergy;
-      
-      MeshFunctionPointer pressure, velocity, rho, rhoVel, energy;
-      
-      RealType gamma;
+                           MeshDependentDataPointer& meshDependentData );*/
 
 
+   protected:
 };
 
-} // namepsace TNL
+} // namespace TNL
 
-#include "eulerProblem_impl.h"
+#include "transportEquationProblemEoc_impl.h"
 
-#endif /* eulerPROBLEM_H_ */
diff --git a/examples/transport-equation/transportEquationProblemEoc_impl.h b/examples/transport-equation/transportEquationProblemEoc_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e2accc3a1413d43b6bdd993916660f54e857b83
--- /dev/null
+++ b/examples/transport-equation/transportEquationProblemEoc_impl.h
@@ -0,0 +1,151 @@
+/***************************************************************************
+                          transportEquationProblemEoc_impl.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/FileName.h>
+#include <TNL/Matrices/MatrixSetter.h>
+#include <TNL/Solvers/PDE/ExplicitUpdater.h>
+#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
+#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
+#include <TNL/Functions/Analytic/Paraboloid.h>
+#include <TNL/Operators/Analytic/Heaviside.h>
+#include <TNL/Operators/Analytic/Shift.h>
+
+#include "transportEquationProblem.h"
+
+namespace TNL {
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+String
+transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return String( "transportEquationProblemEoc< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+String
+transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return String( "Transport Equation EOC" );
+}
+
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const MeshPointer& meshPointer,
+       const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   if( ! this->velocityField->setup( meshPointer, parameters, prefix + "velocity-field-" ) ||
+       ! this->differentialOperatorPointer->setup( meshPointer, parameters, prefix ) ||
+       ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) )
+      return false;
+   
+   /****
+    * Render the exact solution
+    */
+   const String& initialCondition = parameters.getParameter< String >( "initial-condition" );
+   const double& finalTime = parameters.getParameter< double >( "final-time" );
+   const double& snapshotPeriod = parameters.getParameter< double >( "snapshot-period" );
+   static const int Dimension = Mesh::getMeshDimension();
+   typedef typename MeshPointer::ObjectType MeshType;
+   typedef Functions::MeshFunction< MeshType > MeshFunction;
+   SharedPointer< MeshFunction > u( meshPointer );
+   if( initialCondition == "heaviside-vector-norm" )
+   {
+      typedef Functions::Analytic::VectorNorm< Dimension, RealType > VectorNormType;
+      typedef Operators::Analytic::Heaviside< Dimension, RealType > HeavisideType;
+      typedef Functions::OperatorFunction< HeavisideType, VectorNormType > InitialConditionType;
+      String velocityFieldType = parameters.getParameter< String >( "velocity-field" );
+      if( velocityFieldType == "constant" )
+      {      
+         typedef Operators::Analytic::Shift< Dimension, RealType > ShiftOperatorType;
+         typedef Functions::OperatorFunction< ShiftOperatorType, InitialConditionType > ExactSolutionType;
+         SharedPointer< ExactSolutionType, Devices::Host > exactSolution;
+         if( ! exactSolution->getFunction().setup( parameters, prefix + "vector-norm-" ) ||
+             ! exactSolution->getOperator().setup( parameters, prefix + "heaviside-" ) )
+            return false;
+         Containers::StaticVector< Dimension, RealType > velocity;
+         for( int i = 0; i < Dimension; i++ )
+            velocity[ i ] = parameters.getParameter< double >( "velocity-field-" + String( i ) + "-constant" );
+
+         Functions::MeshFunctionEvaluator< MeshFunction, ExactSolutionType > evaluator;
+         RealType time( 0.0 );
+         int step( 0 );
+         exactSolution->getOperator().setShift( 0.0 * velocity );
+         evaluator.evaluate( u, exactSolution, time );
+         FileName fileName;
+         fileName.setFileNameBase( "exact-u-" );
+         fileName.setExtension( "tnl" );
+         fileName.setIndex( step );
+         if( ! u->save( fileName.getFileName() ) )
+            return false;
+         while( time < finalTime )
+         {
+            time += snapshotPeriod;
+            if( time > finalTime )
+               time = finalTime;
+            exactSolution->getOperator().setShift( time * velocity );            
+            std::cerr << time * velocity << std::endl;
+            std::cerr << exactSolution->getOperator().getShift() << std::endl;
+            evaluator.evaluate( u, exactSolution, time );
+            fileName.setIndex( ++step );
+            if( ! u->save( fileName.getFileName() ) )
+               return false;
+         }
+      }
+      if( velocityFieldType == "rotation" )
+      {
+         // TODO: implement this using RotationXY operator
+      }
+   }
+   
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const Config::ParameterContainer& parameters,
+                     const MeshPointer& meshPointer,
+                     DofVectorPointer& dofs,
+                     MeshDependentDataPointer& meshDependentData )
+{
+   this->bindDofs( meshPointer, dofs );
+   //const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
+   FileName fileName;
+   fileName.setFileNameBase( "exact-u-" );
+   fileName.setExtension( "tnl" );
+   fileName.setIndex( 0 );   
+   if( ! this->uPointer->boundLoad( fileName.getFileName() ) )
+   {
+      std::cerr << "I am not able to load the initial condition from the file " << fileName.getFileName() << "." << std::endl;
+      return false;
+   }
+   return true;
+}
+
+} // namespace TNL
diff --git a/examples/transport-equation/transportEquationProblem_impl.h b/examples/transport-equation/transportEquationProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f647802eef18fc9073fdc9b439aa345048d54ea2
--- /dev/null
+++ b/examples/transport-equation/transportEquationProblem_impl.h
@@ -0,0 +1,239 @@
+/***************************************************************************
+                          transportEquationProblem_impl.h  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/FileName.h>
+#include <TNL/Matrices/MatrixSetter.h>
+#include <TNL/Solvers/PDE/ExplicitUpdater.h>
+#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
+#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
+
+#include "transportEquationProblem.h"
+
+namespace TNL {
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+String
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return String( "transportEquationProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+String
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return String( "Transport Equation" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( Logger& logger, const Config::ParameterContainer& 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
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const MeshPointer& meshPointer,
+       const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   if( ! this->velocityField->setup( meshPointer, parameters, prefix + "velocity-field-" ) ||
+       ! this->differentialOperatorPointer->setup( meshPointer, parameters, prefix ) ||
+       ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshPointer& 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
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshPointer& meshPointer,
+          DofVectorPointer& dofVector )
+{
+   const IndexType dofs = meshPointer->template getEntitiesCount< typename MeshType::Cell >();
+   this->uPointer->bind( meshPointer, dofVector );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const Config::ParameterContainer& parameters,
+                     const MeshPointer& meshPointer,
+                     DofVectorPointer& dofs,
+                     MeshDependentDataPointer& meshDependentData )
+{
+   this->bindDofs( meshPointer, dofs );
+   const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
+   if( ! this->uPointer->boundLoad( initialConditionFile ) )
+   {
+      std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
+      return false;
+   }
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+bool
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshPointer& mesh,
+                   Matrix& matrix )
+{
+   /*const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
+   SharedPointer< CompressedRowsLengthsVectorType > rowLengths;
+   if( ! rowLengths->setSize( dofs ) )
+      return false;
+   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh,
+                                                                          differentialOperatorPointer,
+                                                                          boundaryConditionPointer,
+                                                                          rowLengths );
+   matrix->setDimensions( dofs, dofs );
+   if( ! matrix->setCompressedRowsLengths( *rowLengths ) )
+      return false;*/
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+makeSnapshot( const RealType& time,
+              const IndexType& step,
+              const MeshPointer& mesh,
+              DofVectorPointer& dofs,
+              MeshDependentDataPointer& meshDependentData )
+{
+   std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
+   this->bindDofs( mesh, dofs );
+   FileName fileName;
+   fileName.setFileNameBase( "u-" );
+   fileName.setExtension( "tnl" );
+   fileName.setIndex( step );
+   if( ! dofs->save( fileName.getFileName() ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitUpdate( const RealType& time,
+                const RealType& tau,
+                const MeshPointer& mesh,
+                DofVectorPointer& _u,
+                DofVectorPointer& _fu,
+                MeshDependentDataPointer& meshDependentData )
+{
+   /****
+    * If you use an explicit solver like Euler or Merson, 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 >());
+   this->bindDofs( mesh, _u );
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   SharedPointer< MeshFunctionType > u( mesh, _u ); 
+   SharedPointer< MeshFunctionType > fu( mesh, _fu );
+   differentialOperatorPointer->setTau(tau); 
+   differentialOperatorPointer->setVelocityField( this->velocityField );
+   explicitUpdater.setDifferentialOperator( this->differentialOperatorPointer );
+   explicitUpdater.setBoundaryConditions( this->boundaryConditionPointer );
+   explicitUpdater.setRightHandSide( this->rightHandSidePointer );
+   explicitUpdater.template update< typename Mesh::Cell >( time, tau, mesh, u, fu );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+void
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshPointer& mesh,
+                      DofVectorPointer& _u,
+                      Matrix& matrix,
+                      DofVectorPointer& b,
+                      MeshDependentDataPointer& meshDependentData )
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+    template< typename Matrix >
+void
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+saveFailedLinearSystem( const Matrix& matrix,
+                        const DofVectorType& dofs,
+                        const DofVectorType& rightHandSide ) const
+{
+}
+
+} // namespace TNL
diff --git a/install b/install
index c0fc3f6023f3968b999de3f32b3b910ae1d2484b..6ce0b8a60e9d230b73947c65f2a8ef1e2e767fe1 100755
--- a/install
+++ b/install
@@ -35,10 +35,8 @@ then
        mkdir Debug
     fi
     cd Debug
-    if ../build --root-dir=.. --build=Debug ${OPTIONS};
+    if ! ../build --root-dir=.. --build=Debug --install=yes ${OPTIONS}
     then
-        make install
-    else    
        exit 1
     fi
     cd ..
@@ -51,10 +49,8 @@ then
        mkdir Release
     fi
     cd Release
-    if ../build --root-dir=.. --build=Release ${OPTIONS};
+    if ! ../build --root-dir=.. --build=Release --install=yes ${OPTIONS};
     then
-        make install
-    else
         exit 1
     fi
     cd ..
@@ -107,27 +103,5 @@ then
     BUILD_PREFIX="Debug"
 fi
 
-
-PYTHON_TEST="`python src/Tools/python-path-test.py 2> /dev/null`"
-#echo "xxxxx ${PYTHON_TEST} xxxxx\n"
-if test PYTHON_TEST != "xOK";
-then
-    source ${BUILD_PREFIX}/python-version    
-    echo ""
-    echo "WARNING !!!"
-    echo ""
-    echo "Your system does not see TNL Python modules which were installed right now."
-    echo "You need to add it to your system variables PATH and LD_LIBRARY_PATH."
-    echo "Add the following to your .bashrc file:"
-    echo ""
-    echo "if test x\${PYTHONPATH} = x;"
-    echo "then"
-    echo "   PYTHONPATH=${PREFIX}/lib/python${PYTHON_VERSION}"
-    echo "else"
-    echo "   PYTHONPATH=\${PYTHONPATH}:${PREFIX}/lib/python${PYTHON_VERSION}"
-    echo "fi" 
-    echo "export PYTHONPATH" 
-fi
-
 exit 0
 
diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/share/Tools/CMakeLists.txt b/share/Tools/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9499c8dfd96ca922535eacf1358fb863762147da..75215d9ec394fea0d12748a53d9bec7bb9e227a9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,4 @@
 ADD_SUBDIRECTORY( Python )
 ADD_SUBDIRECTORY( TNL )
 ADD_SUBDIRECTORY( Tools )
-ADD_SUBDIRECTORY( UnitTests )
\ No newline at end of file
+ADD_SUBDIRECTORY( UnitTests )
diff --git a/src/Python/CMakeLists.txt b/src/Python/CMakeLists.txt
index 82186a4ef123f7d3943a08f97fe7a8f565e312bf..43f58d0805d302d6af5f6c7c5ed0525d612ac529 100644
--- a/src/Python/CMakeLists.txt
+++ b/src/Python/CMakeLists.txt
@@ -1,3 +1,2 @@
 INSTALL( FILES __init__.py
-         DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/TNL
-         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+         DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/TNL )
diff --git a/src/TNL/Assert.h b/src/TNL/Assert.h
index ddf2dc9bcd8b2098870d59905079f149eb736f84..ce1f7d10bb05d6f192fbee4dd280d63f9f425537 100644
--- a/src/TNL/Assert.h
+++ b/src/TNL/Assert.h
@@ -1,8 +1,8 @@
 /***************************************************************************
-                          VectorOperationsTester.h  -  description
+                          Assert.h  -  description
                              -------------------
     begin                : Jan 12, 2010
-    copyright            : (C) 2013 by Tomas Oberhuber
+    copyright            : (C) 2013 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
@@ -11,47 +11,370 @@
 #pragma once
 
 /****
- * Debugging assert
+ * The purpose of this file is to define the TNL_ASSERT_* debugging macros as
+ * shown below.
+ *
+ * If the 'NDEBUG' macro is defined, the build is considered to be optimized
+ * and all assert macros are empty. Otherwise, the conditions are checked and
+ * failures lead to the diagnostics message being printed to std::cerr and
+ * program abortion (via 'throw EXIT_FAILURE' statement).
+ *
+ * For the purpose of providing Python bindings it is possible to change the
+ * reporting behaviour by defining the TNL_THROW_ASSERTION_ERROR macro, which
+ * leads to throwing the ::TNL::Assert::AssertionError holding the error
+ * message (which is not printed in this case). The AssertionError class does
+ * not inherit from std::exception to avoid being caught by normal exception
+ * handlers, but the code for Python bindings can use it to translate it to the
+ * Python's AssertionError exception.
+ *
+ * Implemented by: Jakub Klinkovsky
  */
 
-#ifndef NDEBUG
+#if defined(NDEBUG) || defined(HAVE_MIC)
 
+// empty macros for optimized build
+#define TNL_ASSERT_TRUE( val, msg )
+#define TNL_ASSERT_FALSE( val, msg )
+#define TNL_ASSERT_EQ( val1, val2, msg )
+#define TNL_ASSERT_NE( val1, val2, msg )
+#define TNL_ASSERT_LE( val1, val2, msg )
+#define TNL_ASSERT_LT( val1, val2, msg )
+#define TNL_ASSERT_GE( val1, val2, msg )
+#define TNL_ASSERT_GT( val1, val2, msg )
+#define TNL_ASSERT( ___tnl__assert_condition, ___tnl__assert_command )
+
+#else /* #ifdef NDEBUG */
+
+#include <sstream>
 #include <iostream>
-#include <stdlib.h>
-#include <assert.h>
+#include <stdio.h>
 
-#endif
+#include <TNL/Devices/CudaCallable.h>
 
 namespace TNL {
+namespace Assert {
+
+#ifdef TNL_THROW_ASSERTION_ERROR
+// This will be used by the code for Python bindings to translate assertion
+// failures to the Python's AssertionError exception.
+class AssertionError
+{
+public:
+    AssertionError( const std::string& msg )
+       : msg( msg )
+    {}
+
+    const char* what() const
+    {
+       return msg.c_str();
+    }
+
+private:
+    std::string msg;
+};
+
+inline void
+printDiagnosticsHost( const char* assertion,
+                      const char* message,
+                      const char* file,
+                      const char* function,
+                      int line,
+                      const char* diagnostics )
+{
+   std::stringstream str;
+   str << "Assertion '" << assertion << "' failed !!!\n"
+       << "Message: " << message << "\n"
+       << "File: " << file << "\n"
+       << "Function: " << function << "\n"
+       << "Line: " << line << "\n"
+       << "Diagnostics:\n" << diagnostics << std::endl;
+   throw AssertionError( str.str() );
+}
+
+#else // TNL_THROW_ASSERTION_ERROR
+
+// This will be used in regular C++ code
+inline void
+printDiagnosticsHost( const char* assertion,
+                      const char* message,
+                      const char* file,
+                      const char* function,
+                      int line,
+                      const char* diagnostics )
+{
+   std::cerr << "Assertion '" << assertion << "' failed !!!\n"
+             << "Message: " << message << "\n"
+             << "File: " << file << "\n"
+             << "Function: " << function << "\n"
+             << "Line: " << line << "\n"
+             << "Diagnostics:\n" << diagnostics << std::endl;
+}
+#endif // TNL_THROW_ASSERTION_ERROR
+
+__cuda_callable__
+inline void
+printDiagnosticsCuda( const char* assertion,
+                      const char* message,
+                      const char* file,
+                      const char* function,
+                      int line,
+                      const char* diagnostics )
+{
+   printf( "Assertion '%s' failed !!!\n"
+           "Message: %s\n"
+           "File: %s\n"
+           "Function: %s\n"
+           "Line: %d\n"
+           "Diagnostics: %s\n",
+           assertion, message, file, function, line, diagnostics );
+}
+
+__cuda_callable__
+inline void
+fatalFailure()
+{
+#ifdef __CUDA_ARCH__
+   // https://devtalk.nvidia.com/default/topic/509584/how-to-cancel-a-running-cuda-kernel-/
+   // TODO: it is reported as "illegal instruction", but that leads to an abort as well...
+   asm("trap;");
+#else
+   throw EXIT_FAILURE;
+#endif
+}
+
+template< typename T >
+struct Formatter
+{
+   static std::string
+   printToString( const T& value )
+   {
+      ::std::stringstream ss;
+      ss << value;
+      return ss.str();
+   }
+};
+
+template<>
+struct Formatter< bool >
+{
+   static std::string
+   printToString( const bool& value )
+   {
+      if( value ) return "true";
+      else return "false";
+   }
+};
+
+template< typename T1, typename T2 >
+__cuda_callable__ void
+cmpHelperOpFailure( const char* assertion,
+                    const char* message,
+                    const char* file,
+                    const char* function,
+                    int line,
+                    const char* lhs_expression,
+                    const char* rhs_expression,
+                    const T1& lhs_value,
+                    const T2& rhs_value,
+                    const char* op )
+{
+#ifdef __CUDA_ARCH__
+   // diagnostics is not supported - we don't have the machinery
+   // to construct the dynamic error message
+   printDiagnosticsCuda( assertion, message, file, function, line,
+                         "Not supported in CUDA kernels." );
+#else
+   const std::string formatted_lhs_value = Formatter< T1 >::printToString( lhs_value );
+   const std::string formatted_rhs_value = Formatter< T2 >::printToString( rhs_value );
+   std::stringstream str;
+   if( std::string(op) == "==" ) {
+      str << "      Expected: " << lhs_expression;
+      if( formatted_lhs_value != lhs_expression ) {
+         str << "\n      Which is: " << formatted_lhs_value;
+      }
+      str << "\nTo be equal to: " << rhs_expression;
+      if( formatted_rhs_value != rhs_expression ) {
+         str << "\n      Which is: " << formatted_rhs_value;
+      }
+      str << std::endl;
+   }
+   else {
+      str << "Expected: (" << lhs_expression << ") " << op << " (" << rhs_expression << "), "
+          << "actual: " << formatted_lhs_value << " vs " << formatted_rhs_value << std::endl;
+   }
+   printDiagnosticsHost( assertion, message, file, function, line,
+                         str.str().c_str() );
+#endif
+   fatalFailure();
+}
+
+template< typename T1, typename T2 >
+__cuda_callable__ void
+cmpHelperTrue( const char* assertion,
+               const char* message,
+               const char* file,
+               const char* function,
+               int line,
+               const char* expr1,
+               const char* expr2,
+               const T1& val1,
+               const T2& val2 )
+{
+   // explicit cast is necessary, because T1::operator! might not be defined
+   if( ! (bool) val1 )
+      ::TNL::Assert::cmpHelperOpFailure( assertion, message, file, function, line,
+                                         expr1, "true", val1, true, "==" );
+}
+
+template< typename T1, typename T2 >
+__cuda_callable__ void
+cmpHelperFalse( const char* assertion,
+                const char* message,
+                const char* file,
+                const char* function,
+                int line,
+                const char* expr1,
+                const char* expr2,
+                const T1& val1,
+                const T2& val2 )
+{
+   if( val1 )
+      ::TNL::Assert::cmpHelperOpFailure( assertion, message, file, function, line,
+                                         expr1, "false", val1, false, "==" );
+}
 
-#ifndef NDEBUG   
+// A macro for implementing the helper functions needed to implement
+// TNL_ASSERT_??. It is here just to avoid copy-and-paste of similar code.
+#define TNL_IMPL_CMP_HELPER_( op_name, op ) \
+template< typename T1, typename T2 > \
+__cuda_callable__ void \
+cmpHelper##op_name( const char* assertion, \
+                    const char* message, \
+                    const char* file, \
+                    const char* function, \
+                    int line, \
+                    const char* expr1, \
+                    const char* expr2, \
+                    const T1& val1, \
+                    const T2& val2 ) \
+{\
+   if( ! ( (val1) op (val2) ) ) \
+      ::TNL::Assert::cmpHelperOpFailure( assertion, message, file, function, line, \
+                                         expr1, expr2, val1, val2, #op );\
+}
+
+// Implements the helper function for TNL_ASSERT_EQ
+TNL_IMPL_CMP_HELPER_( EQ, == );
+// Implements the helper function for TNL_ASSERT_NE
+TNL_IMPL_CMP_HELPER_( NE, != );
+// Implements the helper function for TNL_ASSERT_LE
+TNL_IMPL_CMP_HELPER_( LE, <= );
+// Implements the helper function for TNL_ASSERT_LT
+TNL_IMPL_CMP_HELPER_( LT, < );
+// Implements the helper function for TNL_ASSERT_GE
+TNL_IMPL_CMP_HELPER_( GE, >= );
+// Implements the helper function for TNL_ASSERT_GT
+TNL_IMPL_CMP_HELPER_( GT, > );
+
+#undef TNL_IMPL_CMP_HELPER_
+
+} // namespace Assert
+} // namespace TNL
+
+// Internal macro wrapping the __PRETTY_FUNCTION__ "magic".
+#if defined( __NVCC__ ) && ( __CUDACC_VER__ < 80000 )
+    #define __TNL_PRETTY_FUNCTION "(not known in CUDA 7.5 or older)"
+#else
+    #define __TNL_PRETTY_FUNCTION __PRETTY_FUNCTION__
+#endif
+
+// Internal macro to compose the string representing the assertion.
+// We can't do it easily at runtime, because we have to support assertions
+// in CUDA kernels, which can't use std::string objects. Instead, we do it
+// at compile time - adjacent strings are joined at the language level.
+#define __TNL_JOIN_STRINGS( val1, op, val2 ) \
+   __STRING( val1 ) " " __STRING( op ) " " __STRING( val2 )
+
+// Internal macro to pass all the arguments to the specified cmpHelperOP
+#define __TNL_ASSERT_PRED2( pred, op, val1, val2, msg ) \
+   pred( __TNL_JOIN_STRINGS( val1, op, val2 ), \
+         msg, __FILE__, __TNL_PRETTY_FUNCTION, __LINE__, \
+         #val1, #val2, val1, val2 )
    
-#ifdef HAVE_CUDA
-#define Assert( ___tnl__assert_condition, ___tnl__assert_command )                                    \
+// Main definitions of the TNL_ASSERT_* macros
+// unary
+#define TNL_ASSERT_TRUE( val, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperTrue, ==, val, true, msg )
+#define TNL_ASSERT_FALSE( val, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperFalse, ==, val, false, msg )
+// binary
+#define TNL_ASSERT_EQ( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperEQ, ==, val1, val2, msg )
+#define TNL_ASSERT_NE( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperNE, !=, val1, val2, msg )
+#define TNL_ASSERT_LE( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperLE, <=, val1, val2, msg )
+#define TNL_ASSERT_LT( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperLT, <,  val1, val2, msg )
+#define TNL_ASSERT_GE( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperGE, >=, val1, val2, msg )
+#define TNL_ASSERT_GT( val1, val2, msg ) \
+   __TNL_ASSERT_PRED2( ::TNL::Assert::cmpHelperGT, >,  val1, val2, msg )
+
+
+
+
+/****
+ * Original assert macro with custom command for diagnostics.
+ */
+
+// __CUDA_ARCH__ is defined by the compiler only for code executed on GPU
+#ifdef __CUDA_ARCH__
+#define TNL_ASSERT( ___tnl__assert_condition, ___tnl__assert_command )                                         \
+   if( ! ( ___tnl__assert_condition ) )                                                                        \
+   {                                                                                                           \
+      printf( "Assertion '%s' failed !!! \n File: %s \n Line: %d \n Diagnostics: Not supported with CUDA.\n",  \
+              __STRING( ___tnl__assert_condition ),                                                            \
+              __FILE__,                                                                                        \
+              __LINE__ );                                                                                      \
+      asm("trap;");                                                                                            \
+   }
+
+#else // #ifdef __CUDA_ARCH__
+#ifdef TNL_THROW_ASSERTION_ERROR
+// This will be used by the code for Python bindings to translate assertion
+// failures to the Python's AssertionError exception.
+#define TNL_ASSERT( ___tnl__assert_condition, ___tnl__assert_command )                                   \
    if( ! ( ___tnl__assert_condition ) )                                                                  \
    {                                                                                                     \
-   printf( "Assertion '%s' failed !!! \n File: %s \n Line: %d \n Diagnostics: Not supported with CUDA.\n", \
-           __STRING( ___tnl__assert_condition ),                                                         \
-           __FILE__,                                                                                     \
-           __LINE__ );                                                                                   \
-                                                              \
+      std::stringstream buffer;                                                                          \
+      auto old = std::cerr.rdbuf( buffer.rdbuf() );                                                      \
+                                                                                                         \
+      std::cerr << "Assertion '" << __STRING( ___tnl__assert_condition ) << "' failed !!!" << std::endl  \
+                << "File: " << __FILE__ << std::endl                                                     \
+                << "Function: " << __PRETTY_FUNCTION__ << std::endl                                      \
+                << "Line: " << __LINE__ << std::endl                                                     \
+                << "Diagnostics: ";                                                                      \
+      ___tnl__assert_command;                                                                            \
+                                                                                                         \
+      std::string msg = buffer.str();                                                                    \
+      std::cerr.rdbuf( old );                                                                            \
+      throw ::TNL::Assert::AssertionError( msg );                                                        \
    }
+#else // #ifdef TNL_THROW_ASSERTION_ERROR
+// This will be used in regular C++ code
+#define TNL_ASSERT( ___tnl__assert_condition, ___tnl__assert_command )                                   \
+   if( ! ( ___tnl__assert_condition ) )                                                                  \
+   {                                                                                                     \
+      std::cerr << "Assertion '" << __STRING( ___tnl__assert_condition ) << "' failed !!!" << std::endl  \
+                << "File: " << __FILE__ << std::endl                                                     \
+                << "Function: " << __TNL_PRETTY_FUNCTION << std::endl                                    \
+                << "Line: " << __LINE__ << std::endl                                                     \
+                << "Diagnostics: ";                                                                      \
+      ___tnl__assert_command;                                                                            \
+      throw EXIT_FAILURE;                                                                                \
+   }
+#endif // #ifdef TNL_THROW_ASSERTION_ERROR
+#endif // #ifdef __CUDA_ARCH__
 
-#else // HAVE_CUDA
-#define Assert( ___tnl__assert_condition, ___tnl__assert_command )                       \
-	if( ! ( ___tnl__assert_condition ) )                                                     \
-	{                                                                                        \
-	std::cerr << "Assertion '" << __STRING( ___tnl__assert_condition ) << "' failed !!!" << std::endl  \
-             << "File: " << __FILE__ << std::endl                                                \
-             << "Function: " << __PRETTY_FUNCTION__ << std::endl                                 \
-             << "Line: " << __LINE__ << std::endl                                                \
-             << "Diagnostics: ";                                                            \
-        ___tnl__assert_command;                                                             \
-        throw EXIT_FAILURE;                                                                 \
-	}
-#endif /* HAVE_CUDA */
-#else /* #ifndef NDEBUG */
-#define Assert( ___tnl__assert_condition, ___tnl__assert_command )
-#endif /* #ifndef NDEBUG */
-
-} // namespace TNL
+#endif // #ifdef NDEBUG
\ No newline at end of file
diff --git a/src/TNL/CMakeLists.txt b/src/TNL/CMakeLists.txt
old mode 100755
new mode 100644
index d3371ab5e82b11bb763efbacb817f2333b85e09d..3bdfaca909298fc323cbcf493c5aabd986e60af0
--- a/src/TNL/CMakeLists.txt
+++ b/src/TNL/CMakeLists.txt
@@ -1,6 +1,8 @@
 ADD_SUBDIRECTORY( Config )
 ADD_SUBDIRECTORY( Containers )
+ADD_SUBDIRECTORY( Debugging )
 ADD_SUBDIRECTORY( Devices )
+ADD_SUBDIRECTORY( Exceptions )
 ADD_SUBDIRECTORY( Experimental )
 ADD_SUBDIRECTORY( Functions )
 ADD_SUBDIRECTORY( Images )
@@ -25,19 +27,17 @@ set( headers
      File_impl.h
      FileName.h
      Object.h
-     List.h
-     List_impl.h
      Logger.h
      Logger_impl.h
      Math.h
      mpi-supp.h
+     ParallelFor.h
      param-types.h
      SharedPointer.h
      SmartPointer.h
      SmartPointersRegister.h
      StaticFor.h
      String.h
-     SystemInfo.h
      Timer.h
      UniquePointer.h )
 
@@ -48,7 +48,6 @@ set( common_SOURCES
      Logger.cpp
      SmartPointersRegister.cpp
      String.cpp
-     SystemInfo.cpp
      Timer.cpp )
      
 set( tnl_SOURCES ${tnl_config_SOURCES}
@@ -93,6 +92,8 @@ if( BUILD_CUDA )
 else( BUILD_CUDA )
    ADD_LIBRARY( tnl${debugExt}-${tnlVersion} SHARED 
                 ${tnl_SOURCES} )
+#ifMIC
+  #TARGET_COMPILE_DEFINITIONS( tnl${debugExt}-${tnlVersion} PUBLIC -DHAVE_MIC )
 endif( BUILD_CUDA )                                    
                
 SET_TARGET_PROPERTIES( tnl${debugExt}-${tnlVersion} PROPERTIES 
diff --git a/src/TNL/Config/CMakeLists.txt b/src/TNL/Config/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Config/ConfigDescription.cpp b/src/TNL/Config/ConfigDescription.cpp
index 6822aec9ce7d0551a2e598ef93f394d95e8bd57b..6145103ef64c155cd8b4387d381e135ce47cba70 100644
--- a/src/TNL/Config/ConfigDescription.cpp
+++ b/src/TNL/Config/ConfigDescription.cpp
@@ -129,7 +129,7 @@ bool Config::ConfigDescription :: checkMissingEntries( Config::ParameterContaine
 {
    int i;
    const int size = entries. getSize();
-   List< String > missingParameters;
+   Containers::List< String > missingParameters;
    for( i = 0; i < size; i ++ )
    {
       const char* entry_name = entries[ i ] -> name. getString();
diff --git a/src/TNL/Config/ConfigDescription.h b/src/TNL/Config/ConfigDescription.h
index 5c210fa6df578267f1134697092ba6cefd454dfb..9fab40b7e8591ef132330fd723cc434666c6210b 100644
--- a/src/TNL/Config/ConfigDescription.h
+++ b/src/TNL/Config/ConfigDescription.h
@@ -11,7 +11,7 @@
 #pragma once
 
 #include <TNL/String.h>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/param-types.h>
 #include <TNL/Config/ConfigEntryType.h>
 #include <TNL/Config/ConfigEntry.h>
@@ -88,13 +88,13 @@ class ConfigDescription
    template< typename EntryType >
    void addEntryEnum( const EntryType& entryEnum )
    {
-      Assert( this->currentEntry,);
+      TNL_ASSERT( this->currentEntry,);
       ( ( ConfigEntry< EntryType >* ) currentEntry )->getEnumValues().Append( entryEnum );
    }
 
    void addEntryEnum( const char* entryEnum )
    {
-      Assert( this->currentEntry,);
+      TNL_ASSERT( this->currentEntry,);
       ( ( ConfigEntry< String >* ) currentEntry )->getEnumValues().Append( String( entryEnum ) );
    }
 
@@ -166,7 +166,7 @@ class ConfigDescription
 
    protected:
 
-   List< ConfigEntryBase* > entries;
+   Containers::List< ConfigEntryBase* > entries;
 
    ConfigEntryBase* currentEntry;
 
diff --git a/src/TNL/Config/ConfigEntry.h b/src/TNL/Config/ConfigEntry.h
index fa452fb4ea0ba23a6bc320434f8de170d9620c24..759a77ef3d52d991c4a1f879a7e1e5390023159d 100644
--- a/src/TNL/Config/ConfigEntry.h
+++ b/src/TNL/Config/ConfigEntry.h
@@ -11,6 +11,7 @@
 #pragma once 
 
 #include <TNL/Config/ConfigEntryBase.h>
+#include <TNL/Containers/List.h>
 
 namespace TNL {
 namespace Config {
@@ -20,7 +21,7 @@ struct ConfigEntry : public ConfigEntryBase
 {
    EntryType defaultValue;
 
-   List< EntryType > enumValues;
+   Containers::List< EntryType > enumValues;
 
    public:
 
@@ -61,7 +62,7 @@ struct ConfigEntry : public ConfigEntryBase
       return convertToString( defaultValue );
    };
 
-   List< EntryType >& getEnumValues()
+   Containers::List< EntryType >& getEnumValues()
    {
       return this->enumValues;
    }
diff --git a/src/TNL/Config/ConfigEntryBase.h b/src/TNL/Config/ConfigEntryBase.h
index 44b6d4e8f5b6a9abb848be88fd69b8ba7e81e4ff..f69729ef5aaaa0d8120307eecfc8608d12742dfc 100644
--- a/src/TNL/Config/ConfigEntryBase.h
+++ b/src/TNL/Config/ConfigEntryBase.h
@@ -43,8 +43,7 @@ struct ConfigEntryBase
 
    virtual void printEnumValues() const {};
 
-   // TODO: Fix this -- uncommenting leads to SIGSEGV (for example in tnl-init)
-   //virtual ~ConfigEntryBase() {};
+   virtual ~ConfigEntryBase() {};
 };
 
 } // namespace Config
diff --git a/src/TNL/Config/ConfigEntryList.h b/src/TNL/Config/ConfigEntryList.h
index 01db24d6d6543bda7b3a12d24fa0772b3313c5ff..e8fabf5c58338177e38fa8a1ef652400c2ac79c7 100644
--- a/src/TNL/Config/ConfigEntryList.h
+++ b/src/TNL/Config/ConfigEntryList.h
@@ -11,6 +11,7 @@
 #pragma once 
 
 #include <TNL/Config/ConfigEntryBase.h>
+#include <TNL/Containers/List.h>
 
 namespace TNL {
 namespace Config {  
@@ -20,7 +21,7 @@ struct ConfigEntryList : public ConfigEntryBase
 {
    EntryType defaultValue;
 
-   List< EntryType > enumValues;
+   Containers::List< EntryType > enumValues;
 
    public:
 
@@ -49,12 +50,12 @@ struct ConfigEntryList : public ConfigEntryBase
 
    String getEntryType() const
    {
-      return TNL::getType< List< EntryType > >();
+      return TNL::getType< Containers::List< EntryType > >();
    }
 
    String getUIEntryType() const
    {
-      return TNL::Config::getUIEntryType< List< EntryType > >();
+      return TNL::Config::getUIEntryType< Containers::List< EntryType > >();
    }
 
    String printDefaultValue() const
@@ -62,7 +63,7 @@ struct ConfigEntryList : public ConfigEntryBase
       return convertToString( defaultValue );
    };
 
-   List< EntryType >& getEnumValues()
+   Containers::List< EntryType >& getEnumValues()
    {
       return this->enumValues;
    }
@@ -84,7 +85,7 @@ struct ConfigEntryList : public ConfigEntryBase
      std::cout << " ";
    }
 
-   bool checkValue( const List< EntryType >& values ) const
+   bool checkValue( const Containers::List< EntryType >& values ) const
    {
       if( this->enumValues.getSize() != 0 )
       {
diff --git a/src/TNL/Config/ConfigEntryType.h b/src/TNL/Config/ConfigEntryType.h
index 0d104cb63add85408a70ecdbad400426e3ee1ee5..4ba052d022dd160ad633983d255b5dbfbb318edb 100644
--- a/src/TNL/Config/ConfigEntryType.h
+++ b/src/TNL/Config/ConfigEntryType.h
@@ -10,6 +10,8 @@
 
 #pragma once 
 
+#include <TNL/Containers/List.h>
+
 namespace TNL {
 namespace Config {
 
@@ -21,10 +23,10 @@ template<> inline String getUIEntryType< bool >()      { return "bool"; };
 template<> inline String getUIEntryType< int >()       { return "integer"; };
 template<> inline String getUIEntryType< double >()    { return "real"; };
 
-template<> inline String getUIEntryType< List< String > >() { return "list of string"; };
-template<> inline String getUIEntryType< List< bool > >()      { return "list of bool"; };
-template<> inline String getUIEntryType< List< int > >()       { return "list of integer"; };
-template<> inline String getUIEntryType< List< double > >()    { return "list of real"; };
+template<> inline String getUIEntryType< Containers::List< String > >() { return "list of string"; };
+template<> inline String getUIEntryType< Containers::List< bool > >()      { return "list of bool"; };
+template<> inline String getUIEntryType< Containers::List< int > >()       { return "list of integer"; };
+template<> inline String getUIEntryType< Containers::List< double > >()    { return "list of real"; };
 
 struct ConfigEntryType
 {
diff --git a/src/TNL/Config/ParameterContainer.cpp b/src/TNL/Config/ParameterContainer.cpp
index ef2b335dae862cef51cff879eb8cf26cfa8f4a3d..b2e77dd5e21d4747cb89dfddf6cb53f4ef423a16 100644
--- a/src/TNL/Config/ParameterContainer.cpp
+++ b/src/TNL/Config/ParameterContainer.cpp
@@ -200,7 +200,7 @@ parseCommandLine( int argc, char* argv[],
             std::cerr << "Missing value for the parameter " << option << "." << std::endl;
             return false;
          }
-         List< String > parsedEntryType;
+         Containers::List< String > parsedEntryType;
          if( ! parseObjectType( entryType, parsedEntryType ) )
          {
             std::cerr << "Internal error: Uknown config entry type " << entryType << "." << std::endl;
@@ -208,26 +208,26 @@ parseCommandLine( int argc, char* argv[],
          }
          if( parsedEntryType[ 0 ] == "List" )
          {
-            List< String >* string_list( 0 );
-            List< bool >* bool_list( 0 );
-            List< int >* integer_list( 0 );
-            List< double >* real_list( 0 );
+            Containers::List< String >* string_list( 0 );
+            Containers::List< bool >* bool_list( 0 );
+            Containers::List< int >* integer_list( 0 );
+            Containers::List< double >* real_list( 0 );
 
             if( parsedEntryType[ 1 ] == "String" )
-               string_list = new List< String >;
+               string_list = new Containers::List< String >;
             if( parsedEntryType[ 1 ] == "bool" )
-               bool_list = new List< bool >;
+               bool_list = new Containers::List< bool >;
             if( parsedEntryType[ 1 ] == "int" )
-               integer_list = new List< int >;
+               integer_list = new Containers::List< int >;
             if( parsedEntryType[ 1 ] == "double" )
-               real_list = new List< double >;
+               real_list = new Containers::List< double >;
  
             while( i < argc && ( ( argv[ i ] )[ 0 ] != '-' || ( atof( argv[ i ] ) < 0.0 && ( integer_list || real_list ) ) ) )
             {
                const char* value = argv[ i ++ ];
                if( string_list )
                {
-                  /*if( ! ( ( ConfigEntry< List< String > >* )  entry )->checkValue( String( value ) ) )
+                  /*if( ! ( ( ConfigEntry< Containers::List< String > >* )  entry )->checkValue( String( value ) ) )
                   {
                      delete string_list;
                      return false;
@@ -246,7 +246,7 @@ parseCommandLine( int argc, char* argv[],
                }
                if( integer_list )
                {
-                  /*if( ! ( ConfigEntry< List< int > >* ) entry->checkValue( atoi( value ) ) )
+                  /*if( ! ( ConfigEntry< Containers::List< int > >* ) entry->checkValue( atoi( value ) ) )
                   {
                      delete integer_list;
                      return false;
@@ -255,7 +255,7 @@ parseCommandLine( int argc, char* argv[],
                }
                if( real_list )
                {
-                  /*if( ! ( ConfigEntry< List< double > >* ) entry->checkValue( atof( value ) ) )
+                  /*if( ! ( ConfigEntry< Containers::List< double > >* ) entry->checkValue( atof( value ) ) )
                   {
                      delete real_list;
                      return false;
@@ -265,22 +265,22 @@ parseCommandLine( int argc, char* argv[],
             }
             if( string_list )
             {
-               parameters. addParameter< List< String > >( option, *string_list );
+               parameters. addParameter< Containers::List< String > >( option, *string_list );
                delete string_list;
             }
             if( bool_list )
             {
-               parameters. addParameter< List< bool > >( option, *bool_list );
+               parameters. addParameter< Containers::List< bool > >( option, *bool_list );
                delete bool_list;
             }
             if( integer_list )
             {
-               parameters. addParameter< List< int > >( option, *integer_list );
+               parameters. addParameter< Containers::List< int > >( option, *integer_list );
                delete integer_list;
             }
             if( real_list )
             {
-               parameters. addParameter< List< double > >( option, *real_list );
+               parameters. addParameter< Containers::List< double > >( option, *real_list );
                delete real_list;
             }
             if( i < argc ) i --;
diff --git a/src/TNL/Config/ParameterContainer.h b/src/TNL/Config/ParameterContainer.h
index 8230490a38de13b80613c201b046995b4ae1ae19..0fe07d424a5a60f03f9f162995e6f9b7295bee01 100644
--- a/src/TNL/Config/ParameterContainer.h
+++ b/src/TNL/Config/ParameterContainer.h
@@ -10,10 +10,11 @@
 
 #pragma once 
 
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/mpi-supp.h>
 #include <TNL/param-types.h>
+//#include <TNL/Debugging/StackBacktrace.h>
 
 namespace TNL {
 namespace Config {   
@@ -62,7 +63,7 @@ class ParameterContainer
 
    template< class T > bool getParameter( const String& name,
                                           T& value,
-                                          bool verbose = false ) const
+                                          bool verbose = true ) const
    {
       int i;
       const int size = parameters. getSize();
@@ -73,7 +74,10 @@ class ParameterContainer
             return true;
          }
       if( verbose )
+      {
          std::cerr << "Missing parameter '" << name << "'." << std::endl;
+         throw(0); //PrintStackBacktrace;
+      }
       return false;
    }
 
@@ -96,7 +100,7 @@ class ParameterContainer
 
    protected:
 
-   List< tnlParameterBase* > parameters;
+   Containers::List< tnlParameterBase* > parameters;
 
 };
 
@@ -124,7 +128,7 @@ setParameter( const String& name,
    {
       if( parameters[ i ] -> name == name )
       {
-         if( parameters[ i ] -> type == getType( value ) )
+         if( parameters[ i ] -> type == TNL::getType< T >() )
          {
             ( ( tnlParameter< T > * ) parameters[ i ] ) -> value = value;
             return true;
@@ -133,7 +137,7 @@ setParameter( const String& name,
          {
             std::cerr << "Parameter " << name << " already exists with different type "
                  << parameters[ i ] -> type << " not "
-                 << getType( value ) << std::endl;
+                 << TNL::getType< T >() << std::endl;
             abort( );
             return false;
          }
diff --git a/src/TNL/Containers/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h
similarity index 59%
rename from src/TNL/Containers/ArrayOperations.h
rename to src/TNL/Containers/Algorithms/ArrayOperations.h
index 042270d5b7455aeb06500a98ddc4b161613b477d..4861cc460262ec74cad2a35400eb472cf2e551dc 100644
--- a/src/TNL/Containers/ArrayOperations.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperations.h
@@ -12,9 +12,11 @@
 
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/MIC.h>
 
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 template< typename DestinationDevice,
           typename SourceDevice = DestinationDevice >
@@ -26,11 +28,11 @@ class ArrayOperations< Devices::Host >
    public:
 
    template< typename Element, typename Index >
-   static bool allocateMemory( Element*& data,
+   static void allocateMemory( Element*& data,
                                const Index size );
 
    template< typename Element >
-   static bool freeMemory( Element* data );
+   static void freeMemory( Element* data );
 
    template< typename Element >
    static void setMemoryElement( Element* data,
@@ -64,7 +66,6 @@ class ArrayOperations< Devices::Host >
    static bool compareMemory( const Element1* destination,
                               const Element2* source,
                               const Index size );
-
 };
 
 template<>
@@ -73,11 +74,11 @@ class ArrayOperations< Devices::Cuda >
    public:
 
    template< typename Element, typename Index >
-   static bool allocateMemory( Element*& data,
+   static void allocateMemory( Element*& data,
                                const Index size );
 
    template< typename Element >
-   static bool freeMemory( Element* data );
+   static void freeMemory( Element* data );
 
    template< typename Element >
    static void setMemoryElement( Element* data,
@@ -86,6 +87,7 @@ class ArrayOperations< Devices::Cuda >
    template< typename Element >
    static Element getMemoryElement( const Element* data );
 
+   // TODO: does not make sense for CUDA - remove?
    template< typename Element, typename Index >
    static Element& getArrayElementReference( Element* data, const Index i );
 
@@ -152,8 +154,96 @@ class ArrayOperations< Devices::Host, Devices::Cuda >
                               const Index size );
 };
 
+
+template<>
+class ArrayOperations< Devices::MIC >
+{
+   public:
+
+   template< typename Element, typename Index >
+   static void allocateMemory( Element*& data,
+                               const Index size );
+
+   template< typename Element >
+   static void freeMemory( Element* data );
+
+   template< typename Element >
+   static void setMemoryElement( Element* data,
+                                 const Element& value );
+
+   template< typename Element >
+   static Element getMemoryElement( const Element* data );
+
+   template< typename Element, typename Index >
+   static Element& getArrayElementReference( Element* data, const Index i );
+
+   template< typename Element, typename Index >
+   static const Element& getArrayElementReference( const Element* data, const Index i );
+
+   template< typename Element, typename Index >
+   static bool setMemory( Element* data,
+                          const Element& value,
+                          const Index size );
+
+   template< typename DestinationElement,
+             typename SourceElement,
+             typename Index >
+   static bool copyMemory( DestinationElement* destination,
+                           const SourceElement* source,
+                           const Index size );
+
+   template< typename Element1,
+             typename Element2,
+             typename Index >
+   static bool compareMemory( const Element1* destination,
+                              const Element2* source,
+                              const Index size );
+};
+
+template<>
+class ArrayOperations< Devices::MIC, Devices::Host >
+{
+   public:
+
+   template< typename DestinationElement,
+             typename SourceElement,
+             typename Index >
+   static bool copyMemory( DestinationElement* destination,
+                           const SourceElement* source,
+                           const Index size );
+
+   template< typename DestinationElement,
+             typename SourceElement,
+             typename Index >
+   static bool compareMemory( const DestinationElement* destination,
+                              const SourceElement* source,
+                              const Index size );
+};
+
+template<>
+class ArrayOperations< Devices::Host, Devices::MIC >
+{
+   public:
+
+   template< typename DestinationElement,
+             typename SourceElement,
+             typename Index >
+   static bool copyMemory( DestinationElement* destination,
+                           const SourceElement* source,
+                           const Index size );
+
+   template< typename DestinationElement,
+             typename SourceElement,
+             typename Index >
+   static bool compareMemory( const DestinationElement* destination,
+                              const SourceElement* source,
+                              const Index size );
+};
+
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/ArrayOperationsHost_impl.h>
-#include <TNL/Containers/ArrayOperationsCuda_impl.h>
+#include <TNL/Containers/Algorithms/ArrayOperationsHost_impl.h>
+#include <TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h>
+#include <TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h>
diff --git a/src/TNL/Containers/ArrayOperationsCuda_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h
similarity index 83%
rename from src/TNL/Containers/ArrayOperationsCuda_impl.h
rename to src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h
index 98dd3526891dd929f94da27e7bccc20c564ccfe0..1465c6250bbcd2510b8ceb50a86f7bd77fc02c6c 100644
--- a/src/TNL/Containers/ArrayOperationsCuda_impl.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h
@@ -11,81 +11,100 @@
 #pragma once 
 
 #include <iostream>
+
 #include <TNL/tnlConfig.h>
 #include <TNL/Math.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
+#include <TNL/Exceptions/CudaBadAlloc.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
 #include <TNL/Containers/Algorithms/reduction-operations.h>
 
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 template< typename Element, typename Index >
-bool ArrayOperations< Devices::Cuda >::allocateMemory( Element*& data,
-                                                    const Index size )
+void
+ArrayOperations< Devices::Cuda >::
+allocateMemory( Element*& data,
+                const Index size )
 {
 #ifdef HAVE_CUDA
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
    if( cudaMalloc( ( void** ) &data,
                    ( size_t ) size * sizeof( Element ) ) != cudaSuccess )
+   {
       data = 0;
-   return checkCudaDevice;
+      throw Exceptions::CudaBadAlloc();
+   }
+   TNL_CHECK_CUDA_DEVICE;
 #else
-   CudaSupportMissingMessage;
-   return false;
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
 template< typename Element >
-bool ArrayOperations< Devices::Cuda >::freeMemory( Element* data )
+void
+ArrayOperations< Devices::Cuda >::
+freeMemory( Element* data )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to free a nullptr." );
 #ifdef HAVE_CUDA
-      checkCudaDevice;
-      cudaFree( data );
-      return checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
+   cudaFree( data );
+   TNL_CHECK_CUDA_DEVICE;
 #else
-      CudaSupportMissingMessage;;
-   return true;
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
 template< typename Element >
-void ArrayOperations< Devices::Cuda >::setMemoryElement( Element* data,
-                                                      const Element& value )
+void
+ArrayOperations< Devices::Cuda >::
+setMemoryElement( Element* data,
+                  const Element& value )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to set data through a nullptr." );
    ArrayOperations< Devices::Cuda >::setMemory( data, value, 1 );
 }
 
 template< typename Element >
-Element ArrayOperations< Devices::Cuda >::getMemoryElement( const Element* data )
+Element
+ArrayOperations< Devices::Cuda >::
+getMemoryElement( const Element* data )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to get data through a nullptr." );
    Element result;
    ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< Element, Element, int >( &result, data, 1 );
    return result;
 }
 
 template< typename Element, typename Index >
-Element& ArrayOperations< Devices::Cuda >::getArrayElementReference( Element* data, const Index i )
+Element&
+ArrayOperations< Devices::Cuda >::
+getArrayElementReference( Element* data, const Index i )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to access data through a nullptr." );
    return data[ i ];
 }
 
 template< typename Element, typename Index >
-const Element& ArrayOperations< Devices::Cuda >::getArrayElementReference( const Element* data, const Index i )
+const
+Element& ArrayOperations< Devices::Cuda >::
+getArrayElementReference( const Element* data, const Index i )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to access data through a nullptr." );
    return data[ i ];
 }
 
 
 #ifdef HAVE_CUDA
 template< typename Element, typename Index >
-__global__ void setArrayValueCudaKernel( Element* data,
-                                         const Index size,
-                                         const Element value )
+__global__ void
+setArrayValueCudaKernel( Element* data,
+                         const Index size,
+                         const Element value )
 {
    Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
    const Index maxGridSize = blockDim. x * gridDim. x;
@@ -98,21 +117,22 @@ __global__ void setArrayValueCudaKernel( Element* data,
 #endif
 
 template< typename Element, typename Index >
-bool ArrayOperations< Devices::Cuda >::setMemory( Element* data,
-                    const Element& value,
-                    const Index size )
+bool
+ArrayOperations< Devices::Cuda >::
+setMemory( Element* data,
+           const Element& value,
+           const Index size )
 {
-   Assert( data, );
+   TNL_ASSERT_TRUE( data, "Attempted to set data through a nullptr." );
 #ifdef HAVE_CUDA
    dim3 blockSize( 0 ), gridSize( 0 );
    blockSize. x = 256;
    Index blocksNumber = ceil( ( double ) size / ( double ) blockSize. x );
    gridSize. x = min( blocksNumber, Devices::Cuda::getMaxGridSize() );
    setArrayValueCudaKernel<<< gridSize, blockSize >>>( data, size, value );
-   return checkCudaDevice;
+   return TNL_CHECK_CUDA_DEVICE;
 #else
-   CudaSupportMissingMessage;;
-   return false;
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
@@ -120,9 +140,10 @@ bool ArrayOperations< Devices::Cuda >::setMemory( Element* data,
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-__global__ void copyMemoryCudaToCudaKernel( DestinationElement* destination,
-                                            const SourceElement* source,
-                                            const Index size )
+__global__ void
+copyMemoryCudaToCudaKernel( DestinationElement* destination,
+                            const SourceElement* source,
+                            const Index size )
 {
    Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
    const Index maxGridSize = blockDim. x * gridDim. x;
@@ -137,45 +158,48 @@ __global__ void copyMemoryCudaToCudaKernel( DestinationElement* destination,
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-bool ArrayOperations< Devices::Cuda >::copyMemory( DestinationElement* destination,
-                                                         const SourceElement* source,
-                                                         const Index size )
+bool
+ArrayOperations< Devices::Cuda >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
 {
-   Assert( destination, );
-   Assert( source, );
-   #ifdef HAVE_CUDA
-      if( std::is_same< DestinationElement, SourceElement >::value )
-      {
-         if( cudaMemcpy( destination,
-                         source,
-                         size * sizeof( DestinationElement ),
-                         cudaMemcpyDeviceToDevice ) != cudaSuccess )
-         return checkCudaDevice;
-      }
-      else
-      {
-         dim3 blockSize( 0 ), gridSize( 0 );
-         blockSize. x = 256;
-         Index blocksNumber = ceil( ( double ) size / ( double ) blockSize. x );
-         gridSize. x = min( blocksNumber, Devices::Cuda::getMaxGridSize() );
-         copyMemoryCudaToCudaKernel<<< gridSize, blockSize >>>( destination, source, size );
-         return checkCudaDevice;
-      }
-   #else
-      CudaSupportMissingMessage;;
-   #endif
-      return false;
+   TNL_ASSERT_TRUE( destination, "Attempted to copy data to a nullptr." );
+   TNL_ASSERT_TRUE( source, "Attempted to copy data from a nullptr." );
+#ifdef HAVE_CUDA
+   if( std::is_same< DestinationElement, SourceElement >::value )
+   {
+      cudaMemcpy( destination,
+                  source,
+                  size * sizeof( DestinationElement ),
+                  cudaMemcpyDeviceToDevice );
+      return TNL_CHECK_CUDA_DEVICE;
+   }
+   else
+   {
+      dim3 blockSize( 0 ), gridSize( 0 );
+      blockSize. x = 256;
+      Index blocksNumber = ceil( ( double ) size / ( double ) blockSize. x );
+      gridSize. x = min( blocksNumber, Devices::Cuda::getMaxGridSize() );
+      copyMemoryCudaToCudaKernel<<< gridSize, blockSize >>>( destination, source, size );
+      return TNL_CHECK_CUDA_DEVICE;
+   }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 template< typename Element1,
           typename Element2,
           typename Index >
-bool ArrayOperations< Devices::Cuda >::compareMemory( const Element1* destination,
-                                                   const Element2* source,
-                                                   const Index size )
+bool
+ArrayOperations< Devices::Cuda >::
+compareMemory( const Element1* destination,
+               const Element2* source,
+               const Index size )
 {
-   Assert( destination, );
-   Assert( source, );
+   TNL_ASSERT_TRUE( destination, "Attempted to compare data through a nullptr." );
+   TNL_ASSERT_TRUE( source, "Attempted to compare data through a nullptr." );
    //TODO: The parallel reduction on the CUDA device with different element types is needed.
    bool result;
    Algorithms::tnlParallelReductionEqualities< Element1, Index > reductionEqualities;
@@ -190,34 +214,27 @@ bool ArrayOperations< Devices::Cuda >::compareMemory( const Element1* destinatio
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-bool ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory( DestinationElement* destination,
-                                                         const SourceElement* source,
-                                                         const Index size )
+bool
+ArrayOperations< Devices::Host, Devices::Cuda >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
 {
-   Assert( destination, );
-   Assert( source, );
-   #ifdef HAVE_CUDA
+   TNL_ASSERT_TRUE( destination, "Attempted to copy data to a nullptr." );
+   TNL_ASSERT_TRUE( source, "Attempted to copy data from a nullptr." );
+#ifdef HAVE_CUDA
    if( std::is_same< DestinationElement, SourceElement >::value )
    {
-      cudaMemcpy( destination,
-                  source,
-                  size * sizeof( DestinationElement ),
-                  cudaMemcpyDeviceToHost );
-      if( ! checkCudaDevice )
-      {
+      if( cudaMemcpy( destination,
+                      source,
+                      size * sizeof( DestinationElement ),
+                      cudaMemcpyDeviceToHost ) != cudaSuccess )
          std::cerr << "Transfer of data from CUDA device to host failed." << std::endl;
-         return false;
-      }
-      return true;
+      return TNL_CHECK_CUDA_DEVICE;
    }
    else
    {
       SourceElement* buffer = new SourceElement[ Devices::Cuda::getGPUTransferBufferSize() ];
-      if( ! buffer )
-      {
-         std::cerr << "Unable to allocate supporting buffer to transfer data between the CUDA device and the host." << std::endl;
-         return false;
-      }
       Index i( 0 );
       while( i < size )
       {
@@ -226,9 +243,9 @@ bool ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory( DestinationEle
                          min( size - i, Devices::Cuda::getGPUTransferBufferSize() ) * sizeof( SourceElement ),
                          cudaMemcpyDeviceToHost ) != cudaSuccess )
          {
-            checkCudaDevice;
             delete[] buffer;
-            return false;
+            std::cerr << "Transfer of data from CUDA device to host failed." << std::endl;
+            return TNL_CHECK_CUDA_DEVICE;
          }
          Index j( 0 );
          while( j < Devices::Cuda::getGPUTransferBufferSize() && i + j < size )
@@ -240,34 +257,30 @@ bool ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory( DestinationEle
       }
       delete[] buffer;
    }
-   #else
-      CudaSupportMissingMessage;;
-      return false;
-   #endif
    return true;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 
 template< typename Element1,
           typename Element2,
           typename Index >
-bool ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory( const Element1* destination,
-                                                            const Element2* source,
-                                                            const Index size )
+bool
+ArrayOperations< Devices::Host, Devices::Cuda >::
+compareMemory( const Element1* destination,
+               const Element2* source,
+               const Index size )
 {
    /***
     * Here, destination is on host and source is on CUDA device.
     */
-   Assert( destination, );
-   Assert( source, );
-   Assert( size >= 0, std::cerr << "size = " << size );
-   #ifdef HAVE_CUDA
+   TNL_ASSERT_TRUE( destination, "Attempted to compare data through a nullptr." );
+   TNL_ASSERT_TRUE( source, "Attempted to compare data through a nullptr." );
+   TNL_ASSERT_GE( size, 0, "Array size must be non-negative." );
+#ifdef HAVE_CUDA
    Element2* host_buffer = new Element2[ Devices::Cuda::getGPUTransferBufferSize() ];
-   if( ! host_buffer )
-   {
-      std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for comparing data between CUDA GPU and CPU." << std::endl;
-      return false;
-   }
    Index compared( 0 );
    while( compared < size )
    {
@@ -277,10 +290,9 @@ bool ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory( const Eleme
                       transfer * sizeof( Element2 ),
                       cudaMemcpyDeviceToHost ) != cudaSuccess )
       {
-         std::cerr << "Transfer of data from the device failed." << std::endl;
-         checkCudaDevice;
          delete[] host_buffer;
-         return false;
+         std::cerr << "Transfer of data from CUDA device to host failed." << std::endl;
+         return TNL_CHECK_CUDA_DEVICE;
       }
       if( ! ArrayOperations< Devices::Host >::compareMemory( &destination[ compared ], host_buffer, transfer ) )
       {
@@ -291,10 +303,9 @@ bool ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory( const Eleme
    }
    delete[] host_buffer;
    return true;
-   #else
-      CudaSupportMissingMessage;;
-      return false;
-   #endif
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 /****
@@ -303,35 +314,28 @@ bool ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory( const Eleme
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-bool ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( DestinationElement* destination,
-                                                         const SourceElement* source,
-                                                         const Index size )
+bool
+ArrayOperations< Devices::Cuda, Devices::Host >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
 {
-   Assert( destination, );
-   Assert( source, );
-   Assert( size >= 0, std::cerr << "size = " << size );
-   #ifdef HAVE_CUDA
+   TNL_ASSERT_TRUE( destination, "Attempted to copy data to a nullptr." );
+   TNL_ASSERT_TRUE( source, "Attempted to copy data from a nullptr." );
+   TNL_ASSERT_GE( size, 0, "Array size must be non-negative." );
+#ifdef HAVE_CUDA
    if( std::is_same< DestinationElement, SourceElement >::value )
    {
-      cudaMemcpy( destination,
-                  source,
-                  size * sizeof( DestinationElement ),
-                  cudaMemcpyHostToDevice );
-      if( ! checkCudaDevice )
-      {
+      if( cudaMemcpy( destination,
+                      source,
+                      size * sizeof( DestinationElement ),
+                      cudaMemcpyHostToDevice ) != cudaSuccess )
          std::cerr << "Transfer of data from host to CUDA device failed." << std::endl;
-         return false;
-      }
-      return true;
+      return TNL_CHECK_CUDA_DEVICE;
    }
    else
    {
       DestinationElement* buffer = new DestinationElement[ Devices::Cuda::getGPUTransferBufferSize() ];
-      if( ! buffer )
-      {
-         std::cerr << "Unable to allocate supporting buffer to transfer data between the CUDA device and the host." << std::endl;
-         return false;
-      }
       Index i( 0 );
       while( i < size )
       {
@@ -346,31 +350,32 @@ bool ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( DestinationEle
                          j * sizeof( DestinationElement ),
                          cudaMemcpyHostToDevice ) != cudaSuccess )
          {
-            checkCudaDevice;
             delete[] buffer;
-            return false;
+            std::cerr << "Transfer of data from host to CUDA device failed." << std::endl;
+            return TNL_CHECK_CUDA_DEVICE;
          }
          i += j;
       }
       delete[] buffer;
       return true;
    }
-   #else
-      CudaSupportMissingMessage;;
-      return false;
-   #endif
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 template< typename Element1,
           typename Element2,
           typename Index >
-bool ArrayOperations< Devices::Cuda, Devices::Host >::compareMemory( const Element1* hostData,
-                                                            const Element2* deviceData,
-                                                            const Index size )
+bool
+ArrayOperations< Devices::Cuda, Devices::Host >::
+compareMemory( const Element1* hostData,
+               const Element2* deviceData,
+               const Index size )
 {
-   Assert( hostData, );
-   Assert( deviceData, );
-   Assert( size >= 0, std::cerr << "size = " << size );
+   TNL_ASSERT_TRUE( hostData, "Attempted to compare data through a nullptr." );
+   TNL_ASSERT_TRUE( deviceData, "Attempted to compare data through a nullptr." );
+   TNL_ASSERT_GE( size, 0, "Array size must be non-negative." );
    return ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory( deviceData, hostData, size );
 }
 
@@ -651,5 +656,6 @@ extern template bool ArrayOperations< Devices::Cuda >::setMemory< long double, l
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/ArrayOperationsHost_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h
similarity index 89%
rename from src/TNL/Containers/ArrayOperationsHost_impl.h
rename to src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h
index 6bebb34a4e5ff52c5f6cb4ba6804a3073e7ad15f..7390cfdb0e317a036f45c1db7b58d09a18afac0f 100644
--- a/src/TNL/Containers/ArrayOperationsHost_impl.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h
@@ -11,58 +11,78 @@
 #pragma once 
 
 #include <type_traits>
-#include <TNL/tnlConfig.h>
 #include <string.h>
 
+#include <TNL/tnlConfig.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
+
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 template< typename Element, typename Index >
-bool ArrayOperations< Devices::Host >::allocateMemory( Element*& data,
-                                                      const Index size )
+void
+ArrayOperations< Devices::Host >::
+allocateMemory( Element*& data,
+                const Index size )
 {
-   if( ! ( data = new Element[ size ] ) )
-      return false;
-   return true;
+   data = new Element[ size ];
+   // According to the standard, new either throws, or returns non-nullptr.
+   // Some (old) compilers don't comply:
+   // https://stackoverflow.com/questions/550451/will-new-return-null-in-any-case
+   TNL_ASSERT_TRUE( data, "Operator 'new' returned a nullptr. This should never happen - there is "
+                          "either a bug or the compiler does not comply to the standard." );
 }
 
 template< typename Element >
-bool ArrayOperations< Devices::Host >::freeMemory( Element* data )
+void
+ArrayOperations< Devices::Host >::
+freeMemory( Element* data )
 {
    delete[] data;
-   return true;
 }
+
 template< typename Element >
-void ArrayOperations< Devices::Host >::setMemoryElement( Element* data,
-                                                        const Element& value )
+void
+ArrayOperations< Devices::Host >::
+setMemoryElement( Element* data,
+                  const Element& value )
 {
    *data = value;
 };
 
 template< typename Element >
-Element ArrayOperations< Devices::Host >::getMemoryElement( Element* data )
+Element
+ArrayOperations< Devices::Host >::
+getMemoryElement( Element* data )
 {
    return *data;
 };
 
 template< typename Element, typename Index >
-Element& ArrayOperations< Devices::Host >::getArrayElementReference( Element* data,
-                                                                  const Index i )
+Element&
+ArrayOperations< Devices::Host >::
+getArrayElementReference( Element* data,
+                          const Index i )
 {
    return data[ i ];
 };
 
 template< typename Element, typename Index >
-const Element& ArrayOperations< Devices::Host >::getArrayElementReference( const Element* data,
-                                                                       const Index i )
+const Element&
+ArrayOperations< Devices::Host >::
+getArrayElementReference( const Element* data,
+                          const Index i )
 {
    return data[ i ];
 };
 
 template< typename Element, typename Index >
-bool ArrayOperations< Devices::Host >::setMemory( Element* data,
-                                               const Element& value,
-                                               const Index size )
+bool
+ArrayOperations< Devices::Host >::
+setMemory( Element* data,
+           const Element& value,
+           const Index size )
 {
    for( Index i = 0; i < size; i ++ )
       data[ i ] = value;
@@ -72,11 +92,15 @@ bool ArrayOperations< Devices::Host >::setMemory( Element* data,
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-bool ArrayOperations< Devices::Host >::copyMemory( DestinationElement* destination,
-                                                const SourceElement* source,
-                                                const Index size )
+bool
+ArrayOperations< Devices::Host >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
 {
-   if( std::is_same< DestinationElement, SourceElement >::value )
+   if( std::is_same< DestinationElement, SourceElement >::value &&
+       ( std::is_fundamental< DestinationElement >::value ||
+         std::is_pointer< DestinationElement >::value ) )
       memcpy( destination, source, size * sizeof( DestinationElement ) );
    else
       for( Index i = 0; i < size; i ++ )
@@ -87,11 +111,15 @@ bool ArrayOperations< Devices::Host >::copyMemory( DestinationElement* destinati
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
-bool ArrayOperations< Devices::Host >::compareMemory( const DestinationElement* destination,
-                                                   const SourceElement* source,
-                                                   const Index size )
+bool
+ArrayOperations< Devices::Host >::
+compareMemory( const DestinationElement* destination,
+               const SourceElement* source,
+               const Index size )
 {
-   if( std::is_same< DestinationElement, SourceElement >::value )
+   if( std::is_same< DestinationElement, SourceElement >::value &&
+       ( std::is_fundamental< DestinationElement >::value ||
+         std::is_pointer< DestinationElement >::value ) )
    {
       if( memcmp( destination, source, size * sizeof( DestinationElement ) ) != 0 )
          return false;
@@ -284,5 +312,6 @@ extern template bool ArrayOperations< Devices::Host >::setMemory< long double, l
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..754be26878ae64076ec52c61cd793ae132fd12b6
--- /dev/null
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h
@@ -0,0 +1,444 @@
+/***************************************************************************
+                          ArrayOperationsMIC_impl.h  -  description
+                             -------------------
+    begin                : Mar 4, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Vit Hanousek
+
+#pragma once
+
+#include <iostream>
+
+#include <TNL/tnlConfig.h>
+#include <TNL/Math.h>
+#include <TNL/Exceptions/MICSupportMissing.h>
+#include <TNL/Exceptions/MICBadAlloc.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
+#include <TNL/Containers/Algorithms/reduction-operations.h>
+
+namespace TNL {
+namespace Containers {
+namespace Algorithms {
+
+static constexpr std::size_t MIC_STACK_VAR_LIM = 5*1024*1024;
+
+template< typename Element, typename Index >
+void
+ArrayOperations< Devices::MIC >::
+allocateMemory( Element*& data,
+                const Index size )
+{
+#ifdef HAVE_MIC
+   data = (Element*) Devices::MIC::AllocMIC( size * sizeof(Element) );
+   if( ! data )
+      throw Exceptions::MICBadAlloc();
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+template< typename Element >
+void
+ArrayOperations< Devices::MIC >::
+freeMemory( Element* data )
+{
+   TNL_ASSERT( data, );
+#ifdef HAVE_MIC
+   Devices::MIC::FreeMIC( data );
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+template< typename Element >
+void
+ArrayOperations< Devices::MIC >::
+setMemoryElement( Element* data,
+                  const Element& value )
+{
+   TNL_ASSERT( data, );
+   ArrayOperations< Devices::MIC >::setMemory( data, value, 1 );
+}
+
+template< typename Element >
+Element
+ArrayOperations< Devices::MIC >::
+getMemoryElement( const Element* data )
+{
+   TNL_ASSERT( data, );
+   Element result;
+   ArrayOperations< Devices::Host, Devices::MIC >::copyMemory< Element, Element, int >( &result, data, 1 );
+   return result;
+}
+
+template< typename Element, typename Index >
+Element&
+ArrayOperations< Devices::MIC >::
+getArrayElementReference( Element* data, const Index i )
+{
+   TNL_ASSERT( data, );
+   return data[ i ];
+}
+
+template< typename Element, typename Index >
+const
+Element& ArrayOperations< Devices::MIC >::
+getArrayElementReference( const Element* data, const Index i )
+{
+   TNL_ASSERT( data, );
+   return data[ i ];
+}
+
+template< typename Element, typename Index >
+bool
+ArrayOperations< Devices::MIC >::
+setMemory( Element* data,
+           const Element& value,
+           const Index size )
+{
+   TNL_ASSERT( data, );
+#ifdef HAVE_MIC
+   Element tmp=value;
+   Devices::MICHider<Element> hide_ptr;
+   hide_ptr.pointer=data;
+   #pragma offload target(mic) in(hide_ptr,tmp,size)
+   {
+       Element * dst= hide_ptr.pointer;
+       for(int i=0;i<size;i++)
+           dst[i]=tmp;
+   }
+   return true;
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+template< typename DestinationElement,
+          typename SourceElement,
+          typename Index >
+bool
+ArrayOperations< Devices::MIC >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
+{
+   TNL_ASSERT( destination, );
+   TNL_ASSERT( source, );
+   #ifdef HAVE_MIC
+      if( std::is_same< DestinationElement, SourceElement >::value )
+      {
+         Devices::MICHider<void> src_ptr;
+         src_ptr.pointer=(void*)source;
+         Devices::MICHider<void> dst_ptr;
+         dst_ptr.pointer=(void*)destination;
+         #pragma offload target(mic) in(src_ptr,dst_ptr,size)
+         {
+             memcpy(dst_ptr.pointer,src_ptr.pointer,size*sizeof(DestinationElement));
+         }
+         return true;
+      }
+      else
+      {
+         Devices::MICHider<const SourceElement> src_ptr;
+         src_ptr.pointer=source;
+         Devices::MICHider<DestinationElement> dst_ptr;
+         dst_ptr.pointer=destination;
+         #pragma offload target(mic) in(src_ptr,dst_ptr,size)
+         {
+             for(int i=0;i<size;i++)
+                 dst_ptr.pointer[i]=src_ptr.pointer[i];
+         }
+         return true;
+
+      }
+   #else
+      throw Exceptions::MICSupportMissing();
+   #endif
+      return false;
+}
+
+template< typename Element1,
+          typename Element2,
+          typename Index >
+bool
+ArrayOperations< Devices::MIC >::
+compareMemory( const Element1* destination,
+               const Element2* source,
+               const Index size )
+{
+   TNL_ASSERT( destination, );
+   TNL_ASSERT( source, );
+#ifdef HAVE_MIC
+   if( std::is_same< Element1, Element2 >::value )
+   {
+      Devices::MICHider<void> src_ptr;
+      src_ptr.pointer=(void*)source;
+      Devices::MICHider<void> dst_ptr;
+      dst_ptr.pointer=(void*)destination;
+      int ret=0;
+      #pragma offload target(mic) in(src_ptr,dst_ptr,size) out(ret)
+      {
+          ret=memcmp(dst_ptr.pointer,src_ptr.pointer,size*sizeof(Element1));
+      }
+      if(ret==0)
+          return true;
+   }
+   else
+   {
+      Devices::MICHider<const Element1> src_ptr;
+      src_ptr.pointer=source;
+      Devices::MICHider<const Element2> dst_ptr;
+      dst_ptr.pointer=destination;
+      bool ret=false;
+      #pragma offload target(mic) in(src_ptr,dst_ptr,size) out(ret)
+      {
+          int i=0;
+          for(i=0;i<size;i++)
+              if(dst_ptr.pointer[i]!=src_ptr.pointer[i])
+                  break;
+          if(i==size)
+              ret=true;
+          else
+              ret=false;
+      }
+      return ret;
+   }
+   return false;
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+/****
+ * Operations MIC -> Host
+ */
+
+template< typename DestinationElement,
+          typename SourceElement,
+          typename Index >
+bool
+ArrayOperations< Devices::Host, Devices::MIC >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
+{
+   TNL_ASSERT( destination, );
+   TNL_ASSERT( source, );
+#ifdef HAVE_MIC
+   if( std::is_same< DestinationElement, SourceElement >::value )
+   {
+      Devices::MICHider<void> src_ptr;
+      src_ptr.pointer=(void*)source;
+
+      //JAKA KONSTANTA se vejde do stacku 5MB?
+      if(size<MIC_STACK_VAR_LIM)
+      {
+         uint8_t tmp[size*sizeof(SourceElement)];
+
+         #pragma offload target(mic) in(src_ptr,size) out(tmp)
+         {
+              memcpy((void*)&tmp,src_ptr.pointer,size*sizeof(SourceElement));
+         }
+
+         memcpy((void*)destination,(void*)&tmp,size*sizeof(SourceElement));
+         return true;
+      }
+      else
+      {
+          //direct -- pomalejší
+          uint8_t* tmp=(uint8_t*)destination;
+          #pragma offload target(mic) in(src_ptr,size) out(tmp:length(size))
+          {
+              memcpy((void*)tmp,src_ptr.pointer,size*sizeof(SourceElement));
+          }
+          return true;
+      }
+   }
+   else
+   {
+      Devices::MICHider<const SourceElement> src_ptr;
+      src_ptr.pointer=source;
+
+      if(size<MIC_STACK_VAR_LIM)
+      {
+         uint8_t tmp[size*sizeof(DestinationElement)];
+
+         #pragma offload target(mic) in(src_ptr,size) out(tmp)
+         {
+              DestinationElement *dst=(DestinationElement*)&tmp;
+              for(int i=0;i<size;i++)
+                  dst[i]=src_ptr.pointer[i];
+         }
+
+         memcpy((void*)destination,(void*)&tmp,size*sizeof(DestinationElement));
+         return true;
+      }
+      else
+      {
+          //direct pseudo heap-- pomalejší
+          uint8_t* tmp=(uint8_t*)destination;
+          #pragma offload target(mic) in(src_ptr,size) out(tmp:length(size*sizeof(DestinationElement)))
+          {
+              DestinationElement *dst=(DestinationElement*)tmp;
+              for(int i=0;i<size;i++)
+                  dst[i]=src_ptr.pointer[i];
+          }
+          return true;
+      }
+   }
+   return false;
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+
+template< typename Element1,
+          typename Element2,
+          typename Index >
+bool
+ArrayOperations< Devices::Host, Devices::MIC >::
+compareMemory( const Element1* destination,
+               const Element2* source,
+               const Index size )
+{
+   /***
+    * Here, destination is on host and source is on MIC device.
+    */
+   TNL_ASSERT( destination, );
+   TNL_ASSERT( source, );
+   TNL_ASSERT( size >= 0, std::cerr << "size = " << size );
+#ifdef HAVE_MIC
+   Index compared( 0 );
+   Index transfer( 0 );
+   std::size_t max_transfer=MIC_STACK_VAR_LIM/sizeof(Element2);
+   uint8_t host_buffer[max_transfer*sizeof(Element2)];
+
+   Devices::MICHider<const Element2> src_ptr;
+
+   while( compared < size )
+   {
+     transfer=min(size-compared,max_transfer);
+     src_ptr.pointer=source+compared;
+     #pragma offload target(mic) out(host_buffer) in(src_ptr,transfer)
+     {
+         memcpy((void*)&host_buffer,(void*)src_ptr.pointer,transfer*sizeof(Element2));
+     }
+     if( ! ArrayOperations< Devices::Host >::compareMemory( &destination[ compared ], (Element2*)&host_buffer, transfer ) )
+     {
+        return false;
+     }
+     compared += transfer;
+   }
+   return true;
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+/****
+ * Operations Host -> MIC
+ */
+template< typename DestinationElement,
+          typename SourceElement,
+          typename Index >
+bool
+ArrayOperations< Devices::MIC, Devices::Host >::
+copyMemory( DestinationElement* destination,
+            const SourceElement* source,
+            const Index size )
+{
+   TNL_ASSERT( destination, );
+   TNL_ASSERT( source, );
+   TNL_ASSERT( size >= 0, std::cerr << "size = " << size );
+#ifdef HAVE_MIC
+   if( std::is_same< DestinationElement, SourceElement >::value )
+   {
+      Devices::MICHider<void> dst_ptr;
+      dst_ptr.pointer=(void*)destination;
+
+      //JAKA KONSTANTA se vejde do stacku 5MB?
+      if(size<MIC_STACK_VAR_LIM)
+      {
+         uint8_t tmp[size*sizeof(SourceElement)];
+         memcpy((void*)&tmp,(void*)source,size*sizeof(SourceElement));
+
+         #pragma offload target(mic) in(dst_ptr,tmp,size)
+         {
+              memcpy(dst_ptr.pointer,(void*)&tmp,size*sizeof(SourceElement));
+         }
+
+         return true;
+      }
+      else
+      {
+          //direct pseudo heap-- pomalejší
+          uint8_t* tmp=(uint8_t*)source;
+          #pragma offload target(mic) in(dst_ptr,size) in(tmp:length(size))
+          {
+              memcpy(dst_ptr.pointer,(void*)tmp,size*sizeof(SourceElement));
+          }
+          return true;
+      }
+   }
+   else
+   {
+      Devices::MICHider<DestinationElement> dst_ptr;
+      dst_ptr.pointer=destination;
+
+      if(size<MIC_STACK_VAR_LIM)
+      {
+         uint8_t tmp[size*sizeof(SourceElement)];
+         memcpy((void*)&tmp,(void*)source,size*sizeof(SourceElement));
+
+         #pragma offload target(mic) in(dst_ptr,size,tmp)
+         {
+              SourceElement *src=(SourceElement*)&tmp;
+              for(int i=0;i<size;i++)
+                  dst_ptr.pointer[i]=src[i];
+         }
+         return true;
+      }
+      else
+      {
+          //direct pseudo heap-- pomalejší
+          uint8_t* tmp=(uint8_t*)source;
+          #pragma offload target(mic) in(dst_ptr,size) in(tmp:length(size*sizeof(SourceElement)))
+          {
+              SourceElement *src=(SourceElement*)tmp;
+              for(int i=0;i<size;i++)
+                  dst_ptr.pointer[i]=src[i];
+          }
+          return true;
+      }
+   }
+   return false;
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+template< typename Element1,
+          typename Element2,
+          typename Index >
+bool
+ArrayOperations< Devices::MIC, Devices::Host >::
+compareMemory( const Element1* hostData,
+               const Element2* deviceData,
+               const Index size )
+{
+   TNL_ASSERT( hostData, );
+   TNL_ASSERT( deviceData, );
+   TNL_ASSERT( size >= 0, std::cerr << "size = " << size );
+   return ArrayOperations< Devices::Host, Devices::MIC >::compareMemory( deviceData, hostData, size );
+}
+
+} // namespace Algorithms
+} // namespace Containers
+} // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/CMakeLists.txt b/src/TNL/Containers/Algorithms/CMakeLists.txt
old mode 100755
new mode 100644
index ea0148af125ed2c1aa9ce973b54f149ab151f892..89fbb0368766b45a0c9aca161c44ef29bce5db47
--- a/src/TNL/Containers/Algorithms/CMakeLists.txt
+++ b/src/TNL/Containers/Algorithms/CMakeLists.txt
@@ -1,50 +1,24 @@
-set( headers cuda-prefix-sum.h
+ADD_SUBDIRECTORY( TemplateExplicitInstantiation )
+
+set( headers ArrayOperations.h
+             ArrayOperationsHost_impl.h
+             ArrayOperationsCuda_impl.h
+             ArrayOperationsMIC_impl.h
+             cuda-prefix-sum.h
              cuda-prefix-sum_impl.h
-             cuda-reduction.h             
-             cuda-reduction_impl.h
              reduction-operations.h
-             CudaReduction.h
-             CudaReduction_impl.h
-             CudaReductionBuffer.h
              CublasWrapper.h
              CudaMultireductionKernel.h
+             CudaReductionBuffer.h
+             CudaReductionKernel.h
              Multireduction.h
              Multireduction_impl.h
+             Reduction.h
+             Reduction_impl.h
+             VectorOperations.h
+             VectorOperationsHost_impl.h
+             VectorOperationsCuda_impl.h
+             VectorOperationsMIC_impl.h
    )
 
-SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Containers/Algorithms ) 
-IF( BUILD_CUDA )
-   set( tnl_core_cuda_CUDA__SOURCES
-        ${common_SOURCES}
-        ${CURRENT_DIR}/cuda-reduction-sum_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-min_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-max_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-abs-sum_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-abs-min_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-abs-max_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-and_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-or_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-l2-norm_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-lp-norm_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-equalities_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-inequalities_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-scalar-product_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-sum_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-min_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-max_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-abs-sum_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-abs-min_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-abs-max_impl.cu
-        ${CURRENT_DIR}/cuda-reduction-diff-l2-norm_impl.cu        
-        ${CURRENT_DIR}/cuda-reduction-diff-lp-norm_impl.cu        
-        ${CURRENT_DIR}/cuda-prefix-sum_impl.cu
-        PARENT_SCOPE ) 
-endif() 
-
-set( tnl_core_cuda_SOURCES
-     ${common_SOURCES}
-     ${CURRENT_DIR}/cuda-reduction_impl.cpp
-     ${CURRENT_DIR}/cuda-prefix-sum_impl.cpp     
-     PARENT_SCOPE )               
-        
 INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Containers/Algorithms )
diff --git a/src/TNL/Containers/Algorithms/CudaMultireductionKernel.h b/src/TNL/Containers/Algorithms/CudaMultireductionKernel.h
index 8a1280f536796eef6d7997578db16f05a689a63b..bc12d3030a17d95280c949a11f738c61152ed05c 100644
--- a/src/TNL/Containers/Algorithms/CudaMultireductionKernel.h
+++ b/src/TNL/Containers/Algorithms/CudaMultireductionKernel.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          CudaMultireductionKernel.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #ifdef HAVE_CUDA
@@ -20,6 +32,9 @@ namespace Algorithms {
  * architecture so that there are no local memory spills.
  */
 static constexpr int Multireduction_maxThreadsPerBlock = 256;  // must be a power of 2
+static constexpr int Multireduction_registersPerThread = 38;   // empirically determined optimal value
+
+// __CUDA_ARCH__ is defined only in device code!
 #if (__CUDA_ARCH__ >= 300 )
    static constexpr int Multireduction_minBlocksPerMultiprocessor = 6;
 #else
@@ -29,7 +44,7 @@ static constexpr int Multireduction_maxThreadsPerBlock = 256;  // must be a powe
 template< typename Operation, int blockSizeX >      
 __global__ void
 __launch_bounds__( Multireduction_maxThreadsPerBlock, Multireduction_minBlocksPerMultiprocessor )
-CudaMultireductionKernel( Operation& operation,
+CudaMultireductionKernel( Operation operation,
                           const typename Operation::IndexType n,
                           const typename Operation::IndexType size,
                           const typename Operation::RealType* input1,
@@ -40,9 +55,7 @@ CudaMultireductionKernel( Operation& operation,
    typedef typename Operation::IndexType IndexType;
    typedef typename Operation::ResultType ResultType;
 
-   extern __shared__ __align__ ( 8 ) char __sdata[];
-
-   ResultType* sdata = reinterpret_cast< ResultType* >( __sdata );
+   ResultType* sdata = Devices::Cuda::getSharedMemory< ResultType >();
 
    /***
     * Get thread id (tid) and global element id (gid).
@@ -177,12 +190,14 @@ CudaMultireductionKernelLauncher( Operation& operation,
    // we run the kernel with a fixed number of blocks, so the amount of work per
    // block increases with enlarging the problem, so even small imbalance can
    // cost us dearly.
-   // On Tesla K40c, desGridSizeX = 4 * 6 * 15 = 360.
-//   const IndexType desGridSizeX = 4 * Multireduction_minBlocksPerMultiprocessor
-//                                    * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
-   // On Tesla K40c, desGridSizeX = 6 * 15 = 90.
-   const IndexType desGridSizeX = Multireduction_minBlocksPerMultiprocessor
-                                * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+   // Therefore,  desGridSize = blocksPerMultiprocessor * numberOfMultiprocessors
+   // where blocksPerMultiprocessor is determined according to the number of
+   // available registers on the multiprocessor.
+   // On Tesla K40c, desGridSize = 8 * 15 = 120.
+   const int activeDevice = Devices::CudaDeviceInfo::getActiveDevice();
+   const int blocksdPerMultiprocessor = Devices::CudaDeviceInfo::getRegistersPerMultiprocessor( activeDevice )
+                                      / ( Multireduction_maxThreadsPerBlock * Multireduction_registersPerThread );
+   const int desGridSizeX = blocksdPerMultiprocessor * Devices::CudaDeviceInfo::getCudaMultiprocessors( activeDevice );
    dim3 blockSize, gridSize;
    
    // version A: max 16 rows of threads
@@ -216,12 +231,11 @@ CudaMultireductionKernelLauncher( Operation& operation,
       throw 1;
    }
 
-   // create reference to the reduction buffer singleton and set default size
+   // create reference to the reduction buffer singleton and set size
    // (make an overestimate to avoid reallocation on every call if n is increased by 1 each time)
    const size_t buf_size = 8 * ( n / 8 + 1 ) * desGridSizeX * sizeof( ResultType );
-   CudaReductionBuffer & cudaReductionBuffer = CudaReductionBuffer::getInstance();
-   if( ! cudaReductionBuffer.setSize( buf_size ) )
-      throw 1;
+   CudaReductionBuffer& cudaReductionBuffer = CudaReductionBuffer::getInstance();
+   cudaReductionBuffer.setSize( buf_size );
    output = cudaReductionBuffer.template getData< ResultType >();
 
    // when there is only one warp per blockSize.x, we need to allocate two warps
@@ -290,11 +304,11 @@ CudaMultireductionKernelLauncher( Operation& operation,
          <<< gridSize, blockSize, shmem >>>( operation, n, size, input1, ldInput1, input2, output);
          break;
       case   1:
-         Assert( false, std::cerr << "blockSize should not be 1." << std::endl );
+         TNL_ASSERT( false, std::cerr << "blockSize should not be 1." << std::endl );
       default:
-         Assert( false, std::cerr << "Block size is " << blockSize.x << " which is none of 1, 2, 4, 8, 16, 32, 64, 128, 256 or 512." << std::endl );
+         TNL_ASSERT( false, std::cerr << "Block size is " << blockSize.x << " which is none of 1, 2, 4, 8, 16, 32, 64, 128, 256 or 512." << std::endl );
    }
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
 
    // return the size of the output array on the CUDA device
    return gridSize.x;
diff --git a/src/TNL/Containers/Algorithms/CudaReduction.h b/src/TNL/Containers/Algorithms/CudaReduction.h
deleted file mode 100644
index 3fab192e9891777fa7472b69497b22c9f52325fe..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/Algorithms/CudaReduction.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/***************************************************************************
-                          CudaReduction.h  -  description
-                             -------------------
-    begin                : Jun 17, 2015
-    copyright            : (C) 2015 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {
-namespace Algorithms {
-   
-#ifdef HAVE_CUDA
-
-template< typename Operation, int blockSize >
-class CudaReduction
-{
-   public:
-
-      typedef typename Operation::IndexType IndexType;
-      typedef typename Operation::RealType RealType;
-      typedef typename Operation::ResultType ResultType;
-
- 
-      __device__ static void reduce( Operation& operation,
-                                     const IndexType size,
-                                     const RealType* input1,
-                                     const RealType* input2,
-                                     ResultType* output );
-};
- 
-/*template< typename Real, typename Index, int blockSize >
-class CudaReduction< tnlParallelReductionScalarProduct< Real, Index >, blockSize >
-{
-   public:
- 
-      typedef tnlParallelReductionScalarProduct< Real, Index > Operation;
-      typedef typename Operation::IndexType IndexType;
-      typedef typename Operation::RealType RealType;
-      typedef typename Operation::ResultType ResultType;
- 
-      __device__ static void reduce( Operation operation,
-                                     const IndexType size,
-                                     const RealType* input1,
-                                     const RealType* input2,
-                                     ResultType* output );
-};*/
-
-#endif
-
-} // namespace Algorithms
-} // namespace Containers
-} // namespace TNL
-
-#ifdef HAVE_CUDA
-#include <TNL/Containers/Algorithms/CudaReduction_impl.h>
-#endif
-
diff --git a/src/TNL/Containers/Algorithms/CudaReductionBuffer.h b/src/TNL/Containers/Algorithms/CudaReductionBuffer.h
index 3b7a2150267b2a98c845221bd54d95a9ae509fff..2897c7280a6bc61f9b60a9cb3c7b44a94ad20de3 100644
--- a/src/TNL/Containers/Algorithms/CudaReductionBuffer.h
+++ b/src/TNL/Containers/Algorithms/CudaReductionBuffer.h
@@ -8,10 +8,15 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <stdlib.h>
+
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Exceptions/CudaBadAlloc.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 
 namespace TNL {
 namespace Containers {
@@ -20,35 +25,34 @@ namespace Algorithms {
 class CudaReductionBuffer
 {
    public:
-      inline static CudaReductionBuffer& getInstance( size_t size = 0 )
+      inline static CudaReductionBuffer& getInstance()
       {
-         static CudaReductionBuffer instance( size );
+         static CudaReductionBuffer instance;
          return instance;
       }
 
-      inline bool setSize( size_t size )
+      inline void setSize( size_t size )
       {
 #ifdef HAVE_CUDA
          if( size > this->size )
          {
-            if( data ) cudaFree( data );
-            this->size = size;
-            if( cudaMalloc( ( void** ) &this->data, size ) != cudaSuccess )
-            {
-               std::cerr << "I am not able to allocate reduction buffer on the GPU." << std::endl;
+            this->free();
+            if( cudaMalloc( ( void** ) &this->data, size ) != cudaSuccess ) {
                this->data = 0;
+               throw Exceptions::CudaBadAlloc();
             }
-            return checkCudaDevice;
+            this->size = size;
          }
-         else
-            return true;
 #else
-         return false;
+         throw Exceptions::CudaSupportMissing();
 #endif
       }
 
       template< typename Type >
-      Type* getData() { return ( Type* ) this->data; }
+      Type* getData()
+      {
+         return ( Type* ) this->data;
+      }
 
    private:
       // stop the compiler generating methods of copy the object
@@ -56,10 +60,10 @@ class CudaReductionBuffer
       CudaReductionBuffer& operator=( CudaReductionBuffer const& copy ); // Not Implemented
 
       // private constructor of the singleton
-      inline CudaReductionBuffer( size_t size = 0 ): data( 0 ), size( 0 )
+      inline CudaReductionBuffer( size_t size = 0 )
       {
 #ifdef HAVE_CUDA
-         if( size != 0 ) setSize( size );
+         setSize( size );
          atexit( CudaReductionBuffer::free_atexit );
 #endif
       }
@@ -76,17 +80,17 @@ class CudaReductionBuffer
          if( data )
          {
             cudaFree( data );
-            data = 0;
+            data = nullptr;
+            TNL_CHECK_CUDA_DEVICE;
          }
 #endif
       }
 
-      void* data;
+      void* data = nullptr;
 
-      size_t size;
+      size_t size = 0;
 };
 
 } // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
-
diff --git a/src/TNL/Containers/Algorithms/CudaReductionKernel.h b/src/TNL/Containers/Algorithms/CudaReductionKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..a456dad4fa25dacc41f55b79d8fcf6791c5dfd35
--- /dev/null
+++ b/src/TNL/Containers/Algorithms/CudaReductionKernel.h
@@ -0,0 +1,290 @@
+/***************************************************************************
+                          CudaReductionKernel.h  -  description
+                             -------------------
+    begin                : Jun 17, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#ifdef HAVE_CUDA
+#include <cuda.h>
+#endif
+
+#include <TNL/Assert.h>
+#include <TNL/Math.h>
+#include <TNL/Devices/CudaDeviceInfo.h>
+#include <TNL/Containers/Algorithms/CudaReductionBuffer.h>
+
+namespace TNL {
+namespace Containers {
+namespace Algorithms {
+
+#ifdef HAVE_CUDA
+/****
+ * The performance of this kernel is very sensitive to register usage.
+ * Compile with --ptxas-options=-v and configure these constants for given
+ * architecture so that there are no local memory spills.
+ */
+static constexpr int Reduction_maxThreadsPerBlock = 256;  // must be a power of 2
+static constexpr int Reduction_registersPerThread = 32;   // empirically determined optimal value
+
+// __CUDA_ARCH__ is defined only in device code!
+#if (__CUDA_ARCH__ >= 300 )
+   static constexpr int Reduction_minBlocksPerMultiprocessor = 8;
+#else
+   static constexpr int Reduction_minBlocksPerMultiprocessor = 4;
+#endif
+
+template< typename Operation, int blockSize >
+__global__ void
+__launch_bounds__( Reduction_maxThreadsPerBlock, Reduction_minBlocksPerMultiprocessor )
+CudaReductionKernel( Operation operation,
+                     const typename Operation::IndexType size,
+                     const typename Operation::RealType* input1,
+                     const typename Operation::RealType* input2,
+                     typename Operation::ResultType* output )
+{
+   typedef typename Operation::IndexType IndexType;
+   typedef typename Operation::ResultType ResultType;
+
+   ResultType* sdata = Devices::Cuda::getSharedMemory< ResultType >();
+
+   /***
+    * Get thread id (tid) and global thread id (gid).
+    * gridSize is the number of element processed by all blocks at the
+    * same time.
+    */
+   const IndexType tid = threadIdx.x;
+         IndexType gid = blockIdx.x * blockDim. x + threadIdx.x;
+   const IndexType gridSize = blockDim.x * gridDim.x;
+
+   sdata[ tid ] = operation.initialValue();
+   /***
+    * Read data into the shared memory. We start with the
+    * sequential reduction.
+    */
+   while( gid + 4 * gridSize < size )
+   {
+      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
+      operation.cudaFirstReduction( sdata[ tid ], gid + gridSize,     input1, input2 );
+      operation.cudaFirstReduction( sdata[ tid ], gid + 2 * gridSize, input1, input2 );
+      operation.cudaFirstReduction( sdata[ tid ], gid + 3 * gridSize, input1, input2 );
+      gid += 4 * gridSize;
+   }
+   while( gid + 2 * gridSize < size )
+   {
+      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
+      operation.cudaFirstReduction( sdata[ tid ], gid + gridSize,     input1, input2 );
+      gid += 2 * gridSize;
+   }
+   while( gid < size )
+   {
+      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
+      gid += gridSize;
+   }
+   __syncthreads();
+
+
+   //printf( "1: tid %d data %f \n", tid, sdata[ tid ] );
+
+   //return;
+   /***
+    *  Perform the parallel reduction.
+    */
+   if( blockSize >= 1024 )
+   {
+      if( tid < 512 )
+         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 512 ] );
+      __syncthreads();
+   }
+   if( blockSize >= 512 )
+   {
+      if( tid < 256 )
+         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 256 ] );
+      __syncthreads();
+   }
+   if( blockSize >= 256 )
+   {
+      if( tid < 128 )
+         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 128 ] );
+      __syncthreads();
+      //printf( "2: tid %d data %f \n", tid, sdata[ tid ] );
+   }
+
+   if( blockSize >= 128 )
+   {
+      if( tid <  64 )
+         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 64 ] );
+      __syncthreads();
+      //printf( "3: tid %d data %f \n", tid, sdata[ tid ] );
+   }
+
+
+   /***
+    * This runs in one warp so it is synchronized implicitly.
+    */   
+   if( tid < 32 )
+   {
+      volatile ResultType* vsdata = sdata;
+      if( blockSize >= 64 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 32 ] );
+         //printf( "4: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+      // TODO: If blocksize == 32, the following does not work
+      // We do not check if tid < 16. Fix it!!!
+      if( blockSize >= 32 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 16 ] );
+         //printf( "5: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+      if( blockSize >= 16 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 8 ] );
+         //printf( "6: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+      if( blockSize >=  8 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 4 ] );
+         //printf( "7: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+      if( blockSize >=  4 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 2 ] );
+         //printf( "8: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+      if( blockSize >=  2 )
+      {
+         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 1 ] );
+         //printf( "9: tid %d data %f \n", tid, sdata[ tid ] );
+      }
+   }
+
+   /***
+    * Store the result back in the global memory.
+    */
+   if( tid == 0 )
+   {
+      //printf( "Block %d result = %f \n", blockIdx.x, sdata[ 0 ] );
+      output[ blockIdx.x ] = sdata[ 0 ];
+   }
+
+}
+
+template< typename Operation >
+typename Operation::IndexType
+CudaReductionKernelLauncher( Operation& operation,
+                             const typename Operation::IndexType size,
+                             const typename Operation::RealType* input1,
+                             const typename Operation::RealType* input2,
+                             typename Operation::ResultType*& output )
+{
+   typedef typename Operation::IndexType IndexType;
+   typedef typename Operation::RealType RealType;
+   typedef typename Operation::ResultType ResultType;
+
+   // The number of blocks should be a multiple of the number of multiprocessors
+   // to ensure optimum balancing of the load. This is very important, because
+   // we run the kernel with a fixed number of blocks, so the amount of work per
+   // block increases with enlarging the problem, so even small imbalance can
+   // cost us dearly.
+   // Therefore,  desGridSize = blocksPerMultiprocessor * numberOfMultiprocessors
+   // where blocksPerMultiprocessor is determined according to the number of
+   // available registers on the multiprocessor.
+   // On Tesla K40c, desGridSize = 8 * 15 = 120.
+   const int activeDevice = Devices::CudaDeviceInfo::getActiveDevice();
+   const int blocksdPerMultiprocessor = Devices::CudaDeviceInfo::getRegistersPerMultiprocessor( activeDevice )
+                                      / ( Reduction_maxThreadsPerBlock * Reduction_registersPerThread );
+   const int desGridSize = blocksdPerMultiprocessor * Devices::CudaDeviceInfo::getCudaMultiprocessors( activeDevice );
+   dim3 blockSize, gridSize;
+   blockSize.x = Reduction_maxThreadsPerBlock;
+   gridSize.x = min( Devices::Cuda::getNumberOfBlocks( size, blockSize.x ), desGridSize );
+
+   // create reference to the reduction buffer singleton and set size
+   const size_t buf_size = desGridSize * sizeof( ResultType );
+   CudaReductionBuffer& cudaReductionBuffer = CudaReductionBuffer::getInstance();
+   cudaReductionBuffer.setSize( buf_size );
+   output = cudaReductionBuffer.template getData< ResultType >();
+
+   // when there is only one warp per blockSize.x, we need to allocate two warps
+   // worth of shared memory so that we don't index shared memory out of bounds
+   const IndexType shmem = (blockSize.x <= 32)
+            ? 2 * blockSize.x * sizeof( ResultType )
+            : blockSize.x * sizeof( ResultType );
+
+   /***
+    * Depending on the blockSize we generate appropriate template instance.
+    */
+   switch( blockSize.x )
+   {
+      case 512:
+         CudaReductionKernel< Operation, 512 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case 256:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation, 256 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation, 256 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case 128:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation, 128 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation, 128 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case  64:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,  64 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,  64 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case  32:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,  32 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,  32 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case  16:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,  16 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,  16 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+     case   8:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,   8 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,   8 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case   4:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,   4 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,   4 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case   2:
+         cudaFuncSetCacheConfig(CudaReductionKernel< Operation,   2 >, cudaFuncCachePreferShared);
+
+         CudaReductionKernel< Operation,   2 >
+         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
+         break;
+      case   1:
+         TNL_ASSERT( false, std::cerr << "blockSize should not be 1." << std::endl );
+      default:
+         TNL_ASSERT( false, std::cerr << "Block size is " << blockSize. x << " which is none of 1, 2, 4, 8, 16, 32, 64, 128, 256 or 512." );
+   }
+   TNL_CHECK_CUDA_DEVICE;
+
+   // return the size of the output array on the CUDA device
+   return gridSize.x;
+}
+#endif
+
+} // namespace Algorithms
+} // namespace Containers
+} // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/CudaReduction_impl.h b/src/TNL/Containers/Algorithms/CudaReduction_impl.h
deleted file mode 100644
index ad336a0a54cd2a97c3c1a3b9bd4dc6428c10a7b9..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/Algorithms/CudaReduction_impl.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/***************************************************************************
-                          CudaReduction_impl.h  -  description
-                             -------------------
-    begin                : Jun 17, 2015
-    copyright            : (C) 2015 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {
-namespace Algorithms {
-
-template< typename Operation, int blockSize >
-__device__
-void
-CudaReduction< Operation, blockSize >::
-reduce( Operation& operation,
-        const IndexType size,
-        const RealType* input1,
-        const RealType* input2,
-        ResultType* output )
-{
-   extern __shared__ __align__ ( 8 ) char __sdata[];
-
-   ResultType* sdata = reinterpret_cast< ResultType* >( __sdata );
-
-   /***
-    * Get thread id (tid) and global thread id (gid).
-    * gridSize is the number of element processed by all blocks at the
-    * same time.
-    */
-   IndexType tid = threadIdx. x;
-   IndexType gid = blockIdx. x * blockDim. x + threadIdx. x;
-   IndexType gridSize = blockDim. x * gridDim.x;
-
-   sdata[ tid ] = operation.initialValue();
-   /***
-    * Read data into the shared memory. We start with the
-    * sequential reduction.
-    */
-   while( gid + 4 * gridSize < size )
-   {
-      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
-      operation.cudaFirstReduction( sdata[ tid ], gid + gridSize,     input1, input2 );
-      operation.cudaFirstReduction( sdata[ tid ], gid + 2 * gridSize, input1, input2 );
-      operation.cudaFirstReduction( sdata[ tid ], gid + 3 * gridSize, input1, input2 );
-      gid += 4*gridSize;
-   }
-   while( gid + 2 * gridSize < size )
-   {
-      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
-      operation.cudaFirstReduction( sdata[ tid ], gid + gridSize,     input1, input2 );
-      gid += 2*gridSize;
-   }
-   while( gid < size )
-   {
-      operation.cudaFirstReduction( sdata[ tid ], gid,                input1, input2 );
-      gid += gridSize;
-   }
-   __syncthreads();
-
-
-   //printf( "1: tid %d data %f \n", tid, sdata[ tid ] );
-
-   //return;
-   /***
-    *  Perform the parallel reduction.
-    */
-   if( blockSize >= 1024 )
-   {
-      if( tid < 512 )
-         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 512 ] );
-      __syncthreads();
-   }
-   if( blockSize >= 512 )
-   {
-      if( tid < 256 )
-         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 256 ] );
-      __syncthreads();
-   }
-   if( blockSize >= 256 )
-   {
-      if( tid < 128 )
-         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 128 ] );
-      __syncthreads();
-      //printf( "2: tid %d data %f \n", tid, sdata[ tid ] );
-   }
-
-   if( blockSize >= 128 )
-   {
-      if( tid <  64 )
-         operation.commonReductionOnDevice( sdata[ tid ], sdata[ tid + 64 ] );
-      __syncthreads();
-      //printf( "3: tid %d data %f \n", tid, sdata[ tid ] );
-   }
-
-
-   /***
-    * This runs in one warp so it is synchronized implicitly.
-    */
-   if( tid < 32 )
-   {
-      volatile ResultType* vsdata = sdata;
-      if( blockSize >= 64 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 32 ] );
-         //printf( "4: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >= 32 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 16 ] );
-         //printf( "5: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >= 16 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 8 ] );
-         //printf( "6: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  8 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 4 ] );
-         //printf( "7: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  4 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 2 ] );
-         //printf( "8: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  2 )
-      {
-         operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 1 ] );
-         //printf( "9: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-   }
-
-   /***
-    * Store the result back in the global memory.
-    */
-   if( tid == 0 )
-   {
-      //printf( "Block %d result = %f \n", blockIdx.x, sdata[ 0 ] );
-      output[ blockIdx.x ] = sdata[ 0 ];
-   }
-
-}
-
-#ifdef UNDEF
-
-template< typename Real, typename Index, int blockSize >
-__device__
-void
-CudaReduction< tnlParallelReductionScalarProduct< Real, Index >, blockSize >::
-reduce( Operation& operation,
-        const IndexType size,
-        const RealType* input1,
-        const RealType* input2,
-        ResultType* output )
-{
-  extern __shared__ __align__ ( 8 ) char __sdata[];
-
-   ResultType* sdata = reinterpret_cast< ResultType* >( __sdata );
-
-   /***
-    * Get thread id (tid) and global thread id (gid).
-    * gridSize is the number of element processed by all blocks at the
-    * same time.
-    */
-   IndexType tid = threadIdx. x;
-   IndexType gid = blockIdx. x * blockDim. x + threadIdx. x;
-   IndexType gridSize = blockDim. x * gridDim.x;
-
-   /***
-    * Read data into the shared memory. We start with the
-    * sequential reduction.
-    */
-   sdata[ tid ] = ( RealType ) 0;
-   /*while( gid + 4 * gridSize < size )
-   {
-      sdata[ tid ] += input1[ gid                ] * input2[ gid ];
-      sdata[ tid ] += input1[ gid + gridSize     ] * input2[ gid + gridSize ];
-      sdata[ tid ] += input1[ gid + 2 * gridSize ] * input2[ gid + 2 * gridSize ];
-      sdata[ tid ] += input1[ gid + 3 * gridSize ] * input2[ gid + 3 * gridSize ];
-      gid += 4*gridSize;
-   }
-   while( gid + 2 * gridSize < size )
-   {
-      sdata[ tid ] += input1[ gid            ] * input2[ gid ];
-      sdata[ tid ] += input1[ gid + gridSize ] * input2[ gid + gridSize ];
-      gid += 2*gridSize;
-   }*/
-   while( gid < size )
-   {
-      sdata[ tid ] += input1[ gid ] * input2[ gid ];
-      gid += gridSize;
-   }
-   __syncthreads();
-
-   //printf( "1: tid %d data %f \n", tid, sdata[ tid ] );
-
-   /***
-    *  Perform the parallel reduction.
-    */
-   if( blockSize >= 1024 )
-   {
-      if( tid < 512 )
-         sdata[ tid ] += sdata[ tid + 512 ];
-      __syncthreads();
-   }
-   if( blockSize >= 512 )
-   {
-      if( tid < 256 )
-         sdata[ tid ] += sdata[ tid + 256 ];
-      __syncthreads();
-   }
-   if( blockSize >= 256 )
-   {
-      if( tid < 128 )
-         sdata[ tid ] += sdata[ tid + 128 ];
-      __syncthreads();
-      //printf( "2: tid %d data %f \n", tid, sdata[ tid ] );
-   }
-
-   if( blockSize >= 128 )
-   {
-      if( tid <  64 )
-         sdata[ tid ] += sdata[ tid + 64 ];
-      __syncthreads();
-      //printf( "3: tid %d data %f \n", tid, sdata[ tid ] );
-   }
-
-   /***
-    * This runs in one warp so it is synchronized implicitly.
-    */
-   if( tid < 32 )
-   {
-      volatile ResultType* vsdata = sdata;
-      if( blockSize >= 64 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 32 ];
-         //__syncthreads();
-         //printf( "4: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >= 32 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 16 ];
-         //__syncthreads();
-         //printf( "5: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >= 16 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 8 ];
-         //__syncthreads();
-         //printf( "6: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  8 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 4 ];
-         //__syncthreads();
-         //printf( "7: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  4 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 2 ];
-         //__syncthreads();
-         //printf( "8: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-      if( blockSize >=  2 )
-      {
-         vsdata[ tid ] += vsdata[ tid + 1 ];
-         //__syncthreads();
-         //printf( "9: tid %d data %f \n", tid, sdata[ tid ] );
-      }
-   }
-
-   /***
-    * Store the result back in the global memory.
-    */
-   if( tid == 0 )
-   {
-      //printf( "Block %d result = %f \n", blockIdx.x, sdata[ 0 ] );
-      output[ blockIdx.x ] = sdata[ 0 ];
-   }
-}
-
-#endif
-
-} // namespace Algorithms
-} // namespace Containers
-} // namespace TNL
-
diff --git a/src/TNL/Containers/Algorithms/Multireduction.h b/src/TNL/Containers/Algorithms/Multireduction.h
index 4eb3cf7fcdba79cfe989a7434227c9fe5104f1d9..8aa314e754d9657cef49d09c42d0bd544a2848b7 100644
--- a/src/TNL/Containers/Algorithms/Multireduction.h
+++ b/src/TNL/Containers/Algorithms/Multireduction.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          Multireduction.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <TNL/Devices/Host.h>
@@ -42,6 +54,21 @@ public:
            typename Operation::ResultType* hostResult );
 };
 
+template<>
+class Multireduction< Devices::MIC >
+{
+public:
+   template< typename Operation >
+   static bool
+   reduce( Operation& operation,
+           int n,
+           const typename Operation::IndexType size,
+           const typename Operation::RealType* deviceInput1,
+           const typename Operation::IndexType ldInput1,
+           const typename Operation::RealType* deviceInput2,
+           typename Operation::ResultType* hostResult );
+};
+
 } // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/Multireduction_impl.h b/src/TNL/Containers/Algorithms/Multireduction_impl.h
index 1b9076c38d5f31ccc77f65c18e1a241ad741d75a..e5433f045e90c1ce5cd2f4d090b5a2e5a863464c 100644
--- a/src/TNL/Containers/Algorithms/Multireduction_impl.h
+++ b/src/TNL/Containers/Algorithms/Multireduction_impl.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          Multireduction_impl.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include "Multireduction.h"
@@ -5,8 +17,9 @@
 //#define CUDA_REDUCTION_PROFILING
 
 #include <TNL/Assert.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Containers/Algorithms/CudaMultireductionKernel.h>
 
 #ifdef CUDA_REDUCTION_PROFILING
@@ -47,8 +60,8 @@ reduce( Operation& operation,
         typename Operation::ResultType* hostResult )
 {
 #ifdef HAVE_CUDA
-   Assert( n > 0, );
-   Assert( size <= ldInput1, );
+   TNL_ASSERT_GT( n, 0, "The number of datasets must be positive." );
+   TNL_ASSERT_LE( size, ldInput1, "The size of the input cannot exceed its leading dimension." );
 
    typedef typename Operation::IndexType IndexType;
    typedef typename Operation::RealType RealType;
@@ -65,7 +78,7 @@ reduce( Operation& operation,
          return false;
       if( deviceInput2 ) {
          RealType hostArray2[ Multireduction_minGpuDataSize ];
-         if( ! ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray2, deviceInput2, n * size ) )
+         if( ! ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray2, deviceInput2, size ) )
             return false;
          return Multireduction< Devices::Host >::reduce( operation, n, size, hostArray1, ldInput1, hostArray2, hostResult );
       }
@@ -93,7 +106,7 @@ reduce( Operation& operation,
                                                                    deviceAux1 );
    #ifdef CUDA_REDUCTION_PROFILING
       timer.stop();
-      cout << "   Multireduction of " << n << " datasets on GPU to size " << reducedSize << " took " << timer.getRealTime() << " sec. " << endl;
+      std::cout << "   Multireduction of " << n << " datasets on GPU to size " << reducedSize << " took " << timer.getRealTime() << " sec. " << std::endl;
       timer.reset();
       timer.start();
    #endif
@@ -107,18 +120,18 @@ reduce( Operation& operation,
 
    #ifdef CUDA_REDUCTION_PROFILING
       timer.stop();
-      cout << "   Transferring data to CPU took " << timer.getRealTime() << " sec. " << endl;
+      std::cout << "   Transferring data to CPU took " << timer.getRealTime() << " sec. " << std::endl;
       timer.reset();
       timer.start();
    #endif
 
-//   cout << "resultArray = [";
+//   std::cout << "resultArray = [";
 //   for( int i = 0; i < n * reducedSize; i++ ) {
-//      cout << resultArray[ i ];
+//      std::cout << resultArray[ i ];
 //      if( i < n * reducedSize - 1 )
-//         cout << ", ";
+//         std::cout << ", ";
 //   }
-//   cout << "]" << endl;
+//   std::cout << "]" << std::endl;
 
    /***
     * Reduce the data on the host system.
@@ -128,13 +141,12 @@ reduce( Operation& operation,
 
    #ifdef CUDA_REDUCTION_PROFILING
       timer.stop();
-      cout << "   Multireduction of small data set on CPU took " << timer.getRealTime() << " sec. " << endl;
+      std::cout << "   Multireduction of small data set on CPU took " << timer.getRealTime() << " sec. " << std::endl;
    #endif
 
-   return checkCudaDevice;
+   return TNL_CHECK_CUDA_DEVICE;
 #else
-   CudaSupportMissingMessage;
-   return false;
+   throw Exceptions::CudaSupportMissing();
 #endif
 };
 
@@ -159,8 +171,8 @@ reduce( Operation& operation,
         const typename Operation::RealType* input2,
         typename Operation::ResultType* result )
 {
-   Assert( n > 0, );
-   Assert( size <= ldInput1, );
+   TNL_ASSERT_GT( n, 0, "The number of datasets must be positive." );
+   TNL_ASSERT_LE( size, ldInput1, "The size of the input cannot exceed its leading dimension." );
 
    typedef typename Operation::IndexType IndexType;
    typedef typename Operation::RealType RealType;
@@ -238,6 +250,30 @@ reduce( Operation& operation,
    return true;
 }
 
+template< typename Operation >
+bool
+Multireduction< Devices::MIC >::
+reduce( Operation& operation,
+        int n,
+        const typename Operation::IndexType size,
+        const typename Operation::RealType* input1,
+        const typename Operation::IndexType ldInput1,
+        const typename Operation::RealType* input2,
+        typename Operation::ResultType* result )
+{
+   TNL_ASSERT( n > 0, );
+   TNL_ASSERT( size <= ldInput1, );
+
+   typedef typename Operation::IndexType IndexType;
+   typedef typename Operation::RealType RealType;
+   typedef typename Operation::ResultType ResultType;
+
+
+   std::cout << "Not Implemented yet Multireduction< Devices::MIC >::reduce" << std::endl;
+   return true;
+}
+
+
 } // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction.h b/src/TNL/Containers/Algorithms/Reduction.h
similarity index 68%
rename from src/TNL/Containers/Algorithms/cuda-reduction.h
rename to src/TNL/Containers/Algorithms/Reduction.h
index 093c233c165c50e0c73401edff739374279d2158..242d1b7b83fbf8d71aa545630975561aed65c736 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction.h
+++ b/src/TNL/Containers/Algorithms/Reduction.h
@@ -1,8 +1,8 @@
 /***************************************************************************
-                          cuda-reduction.h  -  description
+                          Reduction.h  -  description
                              -------------------
     begin                : Oct 28, 2010
-    copyright            : (C) 2010 by Tomas Oberhuber
+    copyright            : (C) 2010 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
@@ -14,6 +14,14 @@ namespace TNL {
 namespace Containers {
 namespace Algorithms {   
 
+// TODO: rename to
+//   template< typename Device >
+//   class Reduction
+//   {};
+//
+// and make a specialization for Devices::Host (as it is done in Multireduction.h)
+// It should be as fast as all the manual implementations in VectorOperations.
+
 template< typename Operation >
 bool reductionOnCudaDevice( const Operation& operation,
                             const typename Operation :: IndexType size,
@@ -25,5 +33,4 @@ bool reductionOnCudaDevice( const Operation& operation,
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/Algorithms/cuda-reduction_impl.h>
-
+#include <TNL/Containers/Algorithms/Reduction_impl.h>
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction_impl.h b/src/TNL/Containers/Algorithms/Reduction_impl.h
similarity index 95%
rename from src/TNL/Containers/Algorithms/cuda-reduction_impl.h
rename to src/TNL/Containers/Algorithms/Reduction_impl.h
index dce163b67ebb115d9b58a5186899dc6ba2990d9a..e684b44ac5393adf2348b3a6fed45ea8bba57370 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction_impl.h
+++ b/src/TNL/Containers/Algorithms/Reduction_impl.h
@@ -1,8 +1,8 @@
 /***************************************************************************
-                          cuda-reduction_impl.h  -  description
+                          Reduction_impl.h  -  description
                              -------------------
     begin                : Mar 24, 2013
-    copyright            : (C) 2013 by Tomas Oberhuber
+    copyright            : (C) 2013 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
@@ -10,17 +10,15 @@
 
 #pragma once 
 
+#include "Reduction.h"
+
 //#define CUDA_REDUCTION_PROFILING
 
-#ifdef HAVE_CUDA
-#include <cuda.h>
-#endif
 #include <TNL/Assert.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/ArrayOperations.h>
-#include <TNL/Math.h>
-#include <TNL/Containers/Algorithms/CudaReductionBuffer.h>
-#include <TNL/Containers/Algorithms/CudaReduction.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/CudaReductionKernel.h>
 
 #ifdef CUDA_REDUCTION_PROFILING
 #include <iostream>
@@ -39,95 +37,6 @@ namespace Algorithms {
  */
 const int minGPUReductionDataSize = 256;//65536; //16384;//1024;//256;
 
-#ifdef HAVE_CUDA
-
-template< typename Operation, int blockSize >
-__global__ void
-CudaReductionKernel( Operation operation,
-                     const typename Operation::IndexType size,
-                     const typename Operation::RealType* input1,
-                     const typename Operation::RealType* input2,
-                     typename Operation::ResultType* output )
-{
-   typedef CudaReduction< Operation, blockSize > Reduction;
-   Reduction::reduce( operation, size, input1, input2, output );
-};
-
-template< typename Operation >
-typename Operation::IndexType
-reduceOnCudaDevice( Operation& operation,
-                    const typename Operation::IndexType size,
-                    const typename Operation::RealType* input1,
-                    const typename Operation::RealType* input2,
-                    typename Operation::ResultType*& output)
-{
-   typedef typename Operation::IndexType IndexType;
-   typedef typename Operation::RealType RealType;
-   typedef typename Operation::ResultType ResultType;
- 
-   const IndexType desGridSize( minGPUReductionDataSize );
-   dim3 blockSize( 256 ), gridSize( 0 );
-   gridSize.x = min( Devices::Cuda::getNumberOfBlocks( size, blockSize.x ), desGridSize );
- 
-   // create reference to the reduction buffer singleton and set default size
-   CudaReductionBuffer & cudaReductionBuffer = CudaReductionBuffer::getInstance( 8 * minGPUReductionDataSize );
- 
-   if( ! cudaReductionBuffer.setSize( gridSize.x * sizeof( ResultType ) ) )
-      return false;
-   output = cudaReductionBuffer.template getData< ResultType >();
-   IndexType shmem = blockSize.x * sizeof( ResultType );
- 
-   /***
-    * Depending on the blockSize we generate appropriate template instance.
-    */
-   switch( blockSize.x )
-   {
-      case 512:
-         CudaReductionKernel< Operation, 512 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case 256:
-         CudaReductionKernel< Operation, 256 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case 128:
-         CudaReductionKernel< Operation, 128 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case  64:
-         CudaReductionKernel< Operation,  64 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case  32:
-         CudaReductionKernel< Operation,  32 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case  16:
-         CudaReductionKernel< Operation,  16 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-     case   8:
-         CudaReductionKernel< Operation,   8 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case   4:
-         CudaReductionKernel< Operation,   4 >
-        <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-        break;
-      case   2:
-         CudaReductionKernel< Operation,   2 >
-         <<< gridSize, blockSize, shmem >>>( operation, size, input1, input2, output);
-         break;
-      case   1:
-         Assert( false, std::cerr << "blockSize should not be 1." << std::endl );
-      default:
-         Assert( false, std::cerr << "Block size is " << blockSize. x << " which is none of 1, 2, 4, 8, 16, 32, 64, 128, 256 or 512." );
-   }
-   //checkCudaDevice;
-   return gridSize. x;
-}
-#endif
-
 template< typename Operation >
 bool
 reductionOnCudaDevice( Operation& operation,
@@ -143,18 +52,26 @@ reductionOnCudaDevice( Operation& operation,
    typedef typename Operation::ResultType ResultType;
    typedef typename Operation::LaterReductionOperation LaterReductionOperation;
  
+   /***
+    * Only fundamental and pointer types can be safely reduced on host. Complex
+    * objects stored on the device might contain pointers into the device memory,
+    * in which case reduction on host might fail.
+    */
+   constexpr bool can_reduce_all_on_host = std::is_fundamental< RealType >::value || std::is_pointer< RealType >::value;
+   constexpr bool can_reduce_later_on_host = std::is_fundamental< ResultType >::value || std::is_pointer< ResultType >::value;
+
    /***
     * First check if the input array(s) is/are large enough for the reduction on GPU.
     * Otherwise copy it/them to host and reduce on CPU.
     */
-   if( size <= minGPUReductionDataSize )
+   if( can_reduce_all_on_host && size <= minGPUReductionDataSize )
    {
       RealType hostArray1[ minGPUReductionDataSize ];
       RealType hostArray2[ minGPUReductionDataSize ];
-      if( ! Containers::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray1, deviceInput1, size ) )
+      if( ! ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray1, deviceInput1, size ) )
          return false;
       if( deviceInput2 && !
-          Containers::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray2, deviceInput2, size ) )
+          ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( hostArray2, deviceInput2, size ) )
          return false;
       result = operation.initialValue();
       for( IndexType i = 0; i < size; i ++ )
@@ -172,11 +89,11 @@ reductionOnCudaDevice( Operation& operation,
     * Reduce the data on the CUDA device.
     */
    ResultType* deviceAux1( 0 );
-   IndexType reducedSize = reduceOnCudaDevice( operation,
-                                               size,
-                                               deviceInput1,
-                                               deviceInput2,
-                                               deviceAux1 );
+   IndexType reducedSize = CudaReductionKernelLauncher( operation,
+                                                        size,
+                                                        deviceInput1,
+                                                        deviceInput2,
+                                                        deviceAux1 );
    #ifdef CUDA_REDUCTION_PROFILING
       timer.stop();
       std::cout << "   Reduction on GPU to size " << reducedSize << " took " << timer.getRealTime() << " sec. " << std::endl;
@@ -184,40 +101,68 @@ reductionOnCudaDevice( Operation& operation,
       timer.start();
    #endif
 
-   /***
-    * Transfer the reduced data from device to host.
-    */
-   ResultType resultArray[ minGPUReductionDataSize ];
-   if( ! Containers::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< ResultType, ResultType, IndexType >( resultArray, deviceAux1, reducedSize ) )
-      return false;
- 
-   #ifdef CUDA_REDUCTION_PROFILING
-      timer.stop();
-      std::cout << "   Transferring data to CPU took " << timer.getRealTime() << " sec. " << std::endl;
-   #endif
+   if( can_reduce_later_on_host ) {
+      /***
+       * Transfer the reduced data from device to host.
+       */
+      ResultType resultArray[ reducedSize ];
+      if( ! ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< ResultType, ResultType, IndexType >( resultArray, deviceAux1, reducedSize ) )
+         return false;
+    
+      #ifdef CUDA_REDUCTION_PROFILING
+         timer.stop();
+         std::cout << "   Transferring data to CPU took " << timer.getRealTime() << " sec. " << std::endl;
+         timer.reset();
+         timer.start();
+      #endif
+    
+      /***
+       * Reduce the data on the host system.
+       */
+      LaterReductionOperation laterReductionOperation;
+      result = laterReductionOperation. initialValue();
+      for( IndexType i = 0; i < reducedSize; i ++ )
+         result = laterReductionOperation.reduceOnHost( i, result, resultArray, ( ResultType*) 0 );
+    
+      #ifdef CUDA_REDUCTION_PROFILING
+         timer.stop();
+         std::cout << "   Reduction of small data set on CPU took " << timer.getRealTime() << " sec. " << std::endl;
+      #endif
+   }
+   else {
+      /***
+       * Data can't be safely reduced on host, so continue with the reduction on the CUDA device.
+       */
+      LaterReductionOperation laterReductionOperation;
+      while( reducedSize > 1 ) {
+         reducedSize = CudaReductionKernelLauncher( laterReductionOperation,
+                                                    reducedSize,
+                                                    deviceAux1,
+                                                    (ResultType*) 0,
+                                                    deviceAux1 );
+      }
+
+      #ifdef CUDA_REDUCTION_PROFILING
+         timer.stop();
+         std::cout << "   Reduction of small data set on GPU took " << timer.getRealTime() << " sec. " << std::endl;
+         timer.reset();
+         timer.start();
+      #endif
+
+      ResultType resultArray[ 1 ];
+      if( ! ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< ResultType, ResultType, IndexType >( resultArray, deviceAux1, reducedSize ) )
+         return false;
+      result = resultArray[ 0 ];
 
-   #ifdef CUDA_REDUCTION_PROFILING
-      timer.reset();
-      timer.start();
-   #endif
- 
-   /***
-    * Reduce the data on the host system.
-    */
-   LaterReductionOperation laterReductionOperation;
-   result = laterReductionOperation. initialValue();
-   for( IndexType i = 0; i < reducedSize; i ++ )
-      result = laterReductionOperation.reduceOnHost( i, result, resultArray, ( ResultType*) 0 );
- 
-   #ifdef CUDA_REDUCTION_PROFILING
-      timer.stop();
-      std::cout << "   Reduction of small data set on CPU took " << timer.getRealTime() << " sec. " << std::endl;
-   #endif
+      #ifdef CUDA_REDUCTION_PROFILING
+         timer.stop();
+         std::cout << "   Transferring the result to CPU took " << timer.getRealTime() << " sec. " << std::endl;
+      #endif
+   }
  
-   return checkCudaDevice;
+   return TNL_CHECK_CUDA_DEVICE;
 #else
-   CudaSupportMissingMessage;;
-   return false;
+   throw Exceptions::CudaSupportMissing();
 #endif
 };
 
diff --git a/src/TNL/Containers/ArrayOperationsCuda_impl.cpp b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cpp
similarity index 99%
rename from src/TNL/Containers/ArrayOperationsCuda_impl.cpp
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cpp
index 019b4f9ea48237e58237d9b964ce8403f50fee03..33a2aa1e10b4bf43383a3964f35c4bdc60466f32 100644
--- a/src/TNL/Containers/ArrayOperationsCuda_impl.cpp
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cpp
@@ -8,10 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 
 namespace TNL {
 namespace Containers {    
+namespace Algorithms {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -290,8 +291,6 @@ template bool ArrayOperations< Devices::Cuda >::setMemory< long double, long int
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
-
-
-
diff --git a/src/TNL/Containers/ArrayOperationsCuda_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cu
similarity index 99%
rename from src/TNL/Containers/ArrayOperationsCuda_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cu
index 24e2de2063ed17cadba0834cb76de32cadfa7adb..8690a9256c613c07110c6c25df0186683c9254d0 100644
--- a/src/TNL/Containers/ArrayOperationsCuda_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsCuda_impl.cu
@@ -8,10 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 
 namespace TNL {
 namespace Containers {
+namespace Algorithms {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -290,5 +291,6 @@ template bool ArrayOperations< Devices::Cuda >::setMemory< long double, long int
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/ArrayOperationsHost_impl.cpp b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cpp
similarity index 99%
rename from src/TNL/Containers/ArrayOperationsHost_impl.cpp
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cpp
index a684b3608e20d627a92939822b4d9e0db3228cb8..28b2d6d494f968d00f2856c285ec73b8fba45c26 100644
--- a/src/TNL/Containers/ArrayOperationsHost_impl.cpp
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cpp
@@ -8,10 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 
 namespace TNL {
 namespace Containers {    
+namespace Algorithms {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -194,5 +195,6 @@ template bool ArrayOperations< Devices::Host >::setMemory< long double, long int
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
-} // namespace TNL
\ No newline at end of file
+} // namespace TNL
diff --git a/src/TNL/Containers/ArrayOperationsHost_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cu
similarity index 99%
rename from src/TNL/Containers/ArrayOperationsHost_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cu
index 2be45e40951538866bbc6998c9a451988eba916a..5c4f0b8789145a3328088d1f596d65b0ce2caee1 100644
--- a/src/TNL/Containers/ArrayOperationsHost_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/ArrayOperationsHost_impl.cu
@@ -8,10 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 
 namespace TNL {
 namespace Containers {
+namespace Algorithms {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -194,5 +195,6 @@ template bool ArrayOperations< Devices::Host >::setMemory< long double, long int
 
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/CMakeLists.txt b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8770de6f389c2aa8ed7418c620067f8da053f681
--- /dev/null
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/CMakeLists.txt
@@ -0,0 +1,45 @@
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation )
+set( common_SOURCES
+     ${CURRENT_DIR}/VectorOperationsHost_impl.cpp
+)
+IF( BUILD_CUDA )
+   set( tnl_core_cuda_CUDA__SOURCES
+        ${common_SOURCES}
+        ${CURRENT_DIR}/ArrayOperationsHost_impl.cu
+        ${CURRENT_DIR}/ArrayOperationsCuda_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-sum_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-min_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-max_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-abs-sum_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-abs-min_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-abs-max_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-and_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-or_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-l2-norm_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-lp-norm_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-equalities_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-inequalities_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-scalar-product_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-sum_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-min_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-max_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-abs-sum_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-abs-min_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-abs-max_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-l2-norm_impl.cu
+        ${CURRENT_DIR}/cuda-reduction-diff-lp-norm_impl.cu
+        ${CURRENT_DIR}/cuda-prefix-sum_impl.cu
+        ${CURRENT_DIR}/VectorOperationsCuda_impl.cu
+        PARENT_SCOPE )
+ELSE()
+   set( common_SOURCES
+        ${common_SOURCES}
+        ${CURRENT_DIR}/ArrayOperationsHost_impl.cpp
+        ${CURRENT_DIR}/ArrayOperationsCuda_impl.cpp
+   )
+ENDIF()
+
+set( tnl_core_cuda_SOURCES
+     ${common_SOURCES}
+     ${CURRENT_DIR}/cuda-reduction_impl.cpp
+     PARENT_SCOPE )
diff --git a/src/TNL/Containers/VectorOperationsCuda_impl.cpp b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsCuda_impl.cpp
similarity index 100%
rename from src/TNL/Containers/VectorOperationsCuda_impl.cpp
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsCuda_impl.cpp
diff --git a/src/TNL/Containers/VectorOperationsCuda_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsCuda_impl.cu
similarity index 100%
rename from src/TNL/Containers/VectorOperationsCuda_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsCuda_impl.cu
diff --git a/src/TNL/Containers/VectorOperationsHost_impl.cpp b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsHost_impl.cpp
similarity index 100%
rename from src/TNL/Containers/VectorOperationsHost_impl.cpp
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/VectorOperationsHost_impl.cpp
diff --git a/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-prefix-sum_impl.cu
similarity index 100%
rename from src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-prefix-sum_impl.cu
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-abs-max_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-max_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-abs-max_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-max_impl.cu
index 631c94c3a6f7e744e68c571a4709d7fa552fcb79..f4569b196c1b0f56af4d10690d88c4ab320bb780 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-abs-max_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-max_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-abs-min_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-min_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-abs-min_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-min_impl.cu
index b85f6375cdfd82370aff64f0e08c62f52908078a..6206cba87118ad2b347c516ca5896f1eb7a0dcb4 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-abs-min_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-min_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-abs-sum_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-sum_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-abs-sum_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-sum_impl.cu
index 134986e088410f8672544bff97f771870c7b26ba..15819cb4b2e111a6304e1e9c3c2a64d6a914c369 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-abs-sum_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-abs-sum_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
 
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-and_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-and_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-and_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-and_impl.cu
index 5043f7047e72807b4ab5fd522b2c7e6d15befbba..edb30509c62de2803b8bba24d24f3b973aed4a33 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-and_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-and_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-max_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-max_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-max_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-max_impl.cu
index 86e44fde250f48b98df924ed02b611588f5c82bf..d402b1b490660b58df4c76227867944190779559 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-max_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-max_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-min_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-min_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-min_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-min_impl.cu
index e1776f18ac659d8e0d8110dee50e498b5320010c..f954631a6677013319d9e250fe3a6892cf06abcc 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-min_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-min_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-sum_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-sum_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-sum_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-sum_impl.cu
index 68a8852ab5e64abf82d6eae118fb2b65c6efbfb4..3e87fd7c8ec204376bea0db88ffa85282d792390 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-abs-sum_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-abs-sum_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-l2-norm_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-l2-norm_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-l2-norm_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-l2-norm_impl.cu
index 5ed99ebb73bbe2b5f15fa527f5e0239d90f867e0..c0f23b3102e45b51c754b771573129926efde8e8 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-l2-norm_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-l2-norm_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-lp-norm_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-lp-norm_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-lp-norm_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-lp-norm_impl.cu
index 8ef608d4fff8f881aa92917ee6d2cfca794e75bd..a0d4a00262633dafc8b023e927647fd18fb760dd 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-lp-norm_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-lp-norm_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-max_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-max_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-max_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-max_impl.cu
index 93a5618d17778ea97da9b2be862aef263462b67e..3eaf7558b545ee30d4bbcf7de1394e2c7e357bb7 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-max_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-max_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-min_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-min_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-min_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-min_impl.cu
index aed84b9e0cca33ca2be05149750e629602bdd885..9e0a1b447f1e54889f72aca3008c41a626b911ca 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-min_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-min_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-diff-sum_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-sum_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-diff-sum_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-sum_impl.cu
index a7a2276d278305588080ab2004cbcc37385945f8..cbf0958556eb1d6c0b50654a81ecdc17f1c47650 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-diff-sum_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-diff-sum_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-equalities_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-equalities_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-equalities_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-equalities_impl.cu
index 233f3579c062b12363f47e94fb88bd8118822e3b..7b7c322b7e51e54e9ae3c4826391dff661ec3456 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-equalities_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-equalities_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-inequalities_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-inequalities_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-inequalities_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-inequalities_impl.cu
index 9a0e49d0c54b0acf277e87a4d4a1c5e4a9f42dba..08ca8d8bdc421c345d17671d2ea27829de080b82 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-inequalities_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-inequalities_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-l2-norm_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-l2-norm_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-l2-norm_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-l2-norm_impl.cu
index 9a6f3d4da1e56f297855379f0b6153e2d8fe07e2..5169e1a2adc8eed4422221887f663dc15f5d612d 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-l2-norm_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-l2-norm_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-lp-norm_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-lp-norm_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-lp-norm_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-lp-norm_impl.cu
index 003668f9d40980406cb02d349f1a31a50eb8fc35..3d5366013a114a5e5dfe2ec317bfc0015485019c 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-lp-norm_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-lp-norm_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-max_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-max_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-max_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-max_impl.cu
index bfc541589615adc175af670426eb55063e7bbf1c..a2965136d9816f4ad4ba3b5eaf1d29a9c49b7d82 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-max_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-max_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-min_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-min_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-min_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-min_impl.cu
index 9c047fd8f5c2fc3d9f9dad1cb618b0f89db2a27c..2434189c4374574eff2a0a51ad5d8f50da2b833b 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-min_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-min_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-or_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-or_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-or_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-or_impl.cu
index e90d60b206b0d607dd836695361df8217d9c7a31..6e2c9849ec896138b4c8cf106a8922cd2437c8a9 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-or_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-or_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-scalar-product_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-scalar-product_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-scalar-product_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-scalar-product_impl.cu
index 9fcc082fff3caeab8ce223c9b52dcd17b51dad3b..eabb3aff6c912faa88b45727c0082dac0538afea 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-scalar-product_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-scalar-product_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
 
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction-sum_impl.cu b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-sum_impl.cu
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction-sum_impl.cu
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-sum_impl.cu
index 252f6f8fe3bc1c04cbb1e28c0c9a13a708d3274c..79d9263ab4922d91caf08493653a8b1effdc1cf6 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction-sum_impl.cu
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction-sum_impl.cu
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
  
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
  
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/Algorithms/cuda-reduction_impl.cpp b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction_impl.cpp
similarity index 99%
rename from src/TNL/Containers/Algorithms/cuda-reduction_impl.cpp
rename to src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction_impl.cpp
index b3dbbf719ae323edabc08f8cd6b5d00a8a71d51b..ce76fd397eea1d50f6fb873038f0a1223efd72e4 100644
--- a/src/TNL/Containers/Algorithms/cuda-reduction_impl.cpp
+++ b/src/TNL/Containers/Algorithms/TemplateExplicitInstantiation/cuda-reduction_impl.cpp
@@ -9,7 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include <TNL/Containers/Algorithms/reduction-operations.h>
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
 
 namespace TNL {
 namespace Containers {
diff --git a/src/TNL/Containers/VectorOperations.h b/src/TNL/Containers/Algorithms/VectorOperations.h
similarity index 62%
rename from src/TNL/Containers/VectorOperations.h
rename to src/TNL/Containers/Algorithms/VectorOperations.h
index bb8de59506ca28bce639486280fdfb09e1ccbf00..fb24f97c178c8571d081b77496c91101b5a45e31 100644
--- a/src/TNL/Containers/VectorOperations.h
+++ b/src/TNL/Containers/Algorithms/VectorOperations.h
@@ -10,13 +10,14 @@
 
 #pragma once 
 
-#include <TNL/Containers/Algorithms/cuda-reduction.h>
+#include <TNL/Containers/Algorithms/Reduction.h>
 #include <TNL/Containers/Algorithms/reduction-operations.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
 
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 template< typename Device >
 class VectorOperations{};
@@ -64,36 +65,36 @@ class VectorOperations< Devices::Host >
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceMax( const Vector1& v1,
-                                                               const Vector2& v2 );
+                                                             const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceMin( const Vector1& v1,
-                                                               const Vector2& v2 );
+                                                             const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceAbsMax( const Vector1& v1,
-                                                                  const Vector2& v2 );
+                                                                const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceAbsMin( const Vector1& v1,
-                                                                  const Vector2& v2 );
+                                                                const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceL1Norm( const Vector1& v1,
-                                                           const Vector2& v2 );
+                                                                const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceL2Norm( const Vector1& v1,
-                                                           const Vector2& v2 );
+                                                                const Vector2& v2 );
  
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceLpNorm( const Vector1& v1,
-                                                           const Vector2& v2,
-                                                           const typename Vector1::RealType& p );
+                                                                const Vector2& v2,
+                                                                const typename Vector1::RealType& p );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceSum( const Vector1& v1,
-                                                               const Vector2& v2 );
+                                                             const Vector2& v2 );
  
  
    template< typename Vector >
@@ -102,7 +103,7 @@ class VectorOperations< Devices::Host >
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getScalarProduct( const Vector1& v1,
-                                                         const Vector2& v2 );
+                                                       const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static void addVector( Vector1& y,
@@ -127,7 +128,6 @@ class VectorOperations< Devices::Host >
    static void computeExclusivePrefixSum( Vector& v,
                                           const typename Vector::IndexType begin,
                                           const typename Vector::IndexType end );
-
 };
 
 template<>
@@ -177,11 +177,11 @@ class VectorOperations< Devices::Cuda >
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceMin( const Vector1& v1,
-                                                               const Vector2& v2 );
+                                                             const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceAbsMax( const Vector1& v1,
-                                                                  const Vector2& v2 );
+                                                                const Vector2& v2 );
 
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceAbsMin( const Vector1& v1,
@@ -195,6 +195,115 @@ class VectorOperations< Devices::Cuda >
    static typename Vector1::RealType getVectorDifferenceL2Norm( const Vector1& v1,
                                                                 const Vector2& v2 );
  
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceLpNorm( const Vector1& v1,
+                                                                const Vector2& v2,
+                                                                const typename Vector1::RealType& p );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceSum( const Vector1& v1,
+                                                             const Vector2& v2 );
+ 
+   template< typename Vector >
+   static void vectorScalarMultiplication( Vector& v,
+                                           const typename Vector::RealType& alpha );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getScalarProduct( const Vector1& v1,
+                                                       const Vector2& v2 );
+
+   template< typename Vector1, typename Vector2 >
+   static void addVector( Vector1& y,
+                          const Vector2& x,
+                          const typename Vector2::RealType& alpha,
+                          const typename Vector1::RealType& thisMultiplicator = 1.0 );
+ 
+   template< typename Vector1, typename Vector2, typename Vector3 >
+   static void addVectors( Vector1& v,
+                           const Vector2& v1,
+                           const typename Vector2::RealType& multiplicator1,
+                           const Vector3& v2,
+                           const typename Vector3::RealType& multiplicator2,
+                           const typename Vector1::RealType& thisMultiplicator = 1.0 );
+ 
+
+   template< typename Vector >
+   static void computePrefixSum( Vector& v,
+                                 const typename Vector::IndexType begin,
+                                 const typename Vector::IndexType end );
+
+   template< typename Vector >
+   static void computeExclusivePrefixSum( Vector& v,
+                                          const typename Vector::IndexType begin,
+                                          const typename Vector::IndexType end );
+};
+
+#ifdef HAVE_MIC
+template<>
+class VectorOperations< Devices::MIC >
+{
+   public:
+
+   template< typename Vector >
+   static void addElement( Vector& v,
+                           const typename Vector::IndexType i,
+                           const typename Vector::RealType& value );
+
+   template< typename Vector >
+   static void addElement( Vector& v,
+                           const typename Vector::IndexType i,
+                           const typename Vector::RealType& value,
+                           const typename Vector::RealType& thisElementMultiplicator );
+
+   template< typename Vector >
+   static typename Vector::RealType getVectorMax( const Vector& v );
+
+   template< typename Vector >
+   static typename Vector::RealType getVectorMin( const Vector& v );
+
+   template< typename Vector >
+   static typename Vector::RealType getVectorAbsMax( const Vector& v );
+
+   template< typename Vector >
+   static typename Vector::RealType getVectorAbsMin( const Vector& v );
+   
+   template< typename Vector >
+   static typename Vector::RealType getVectorL1Norm( const Vector& v );
+   
+   template< typename Vector >
+   static typename Vector::RealType getVectorL2Norm( const Vector& v );
+   
+   template< typename Vector >
+   static typename Vector::RealType getVectorLpNorm( const Vector& v,
+                                                     const typename Vector::RealType& p );
+   
+   template< typename Vector >
+   static typename Vector::RealType getVectorSum( const Vector& v );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceMax( const Vector1& v1,
+                                                             const Vector2& v2 );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceMin( const Vector1& v1,
+                                                               const Vector2& v2 );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceAbsMax( const Vector1& v1,
+                                                                  const Vector2& v2 );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceAbsMin( const Vector1& v1,
+                                                                const Vector2& v2 );
+  
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceL1Norm( const Vector1& v1,
+                                                                const Vector2& v2 );
+
+   template< typename Vector1, typename Vector2 >
+   static typename Vector1::RealType getVectorDifferenceL2Norm( const Vector1& v1,
+                                                                const Vector2& v2 );
+  
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceLpNorm( const Vector1& v1,
                                                            const Vector2& v2,
@@ -203,7 +312,7 @@ class VectorOperations< Devices::Cuda >
    template< typename Vector1, typename Vector2 >
    static typename Vector1::RealType getVectorDifferenceSum( const Vector1& v1,
                                                                const Vector2& v2 );
- 
+   
    template< typename Vector >
    static void vectorScalarMultiplication( Vector& v,
                                            const typename Vector::RealType& alpha );
@@ -217,7 +326,7 @@ class VectorOperations< Devices::Cuda >
                           const Vector2& x,
                           const typename Vector2::RealType& alpha,
                           const typename Vector1::RealType& thisMultiplicator = 1.0 );
- 
+   
    template< typename Vector1, typename Vector2, typename Vector3 >
    static void addVectors( Vector1& v,
                            const Vector2& v1,
@@ -225,7 +334,7 @@ class VectorOperations< Devices::Cuda >
                            const Vector3& v2,
                            const typename Vector3::RealType& multiplicator2,
                            const typename Vector1::RealType& thisMultiplicator = 1.0 );
- 
+   
 
    template< typename Vector >
    static void computePrefixSum( Vector& v,
@@ -237,10 +346,15 @@ class VectorOperations< Devices::Cuda >
                                           const typename Vector::IndexType begin,
                                           const typename Vector::IndexType end );
 };
+#endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/VectorOperationsHost_impl.h>
-#include <TNL/Containers/VectorOperationsCuda_impl.h>
+#ifdef HAVE_MIC
+#include <TNL/Containers/Algorithms/VectorOperationsMIC_impl.h>
+#endif
+#include <TNL/Containers/Algorithms/VectorOperationsHost_impl.h>
+#include <TNL/Containers/Algorithms/VectorOperationsCuda_impl.h>
 
diff --git a/src/TNL/Containers/VectorOperationsCuda_impl.h b/src/TNL/Containers/Algorithms/VectorOperationsCuda_impl.h
similarity index 67%
rename from src/TNL/Containers/VectorOperationsCuda_impl.h
rename to src/TNL/Containers/Algorithms/VectorOperationsCuda_impl.h
index 3c6774613ef6448be062dcc9c899fcffeb9ad71e..c32f44bbaf3a318a8d43b9116baac563b26cdf5e 100644
--- a/src/TNL/Containers/VectorOperationsCuda_impl.h
+++ b/src/TNL/Containers/Algorithms/VectorOperationsCuda_impl.h
@@ -11,96 +11,111 @@
 #pragma once
 
 #include <TNL/tnlConfig.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
+#include <TNL/Containers/Algorithms/VectorOperations.h>
 #include <TNL/Containers/Algorithms/cuda-prefix-sum.h>
 #include <TNL/Containers/Algorithms/CublasWrapper.h>
 
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 template< typename Vector >
-void VectorOperations< Devices::Cuda >::addElement( Vector& v,
-                                                 const typename Vector::IndexType i,
-                                                 const typename Vector::RealType& value )
+void
+VectorOperations< Devices::Cuda >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value )
 {
    v[ i ] += value;
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Cuda >::addElement( Vector& v,
-                                                 const typename Vector::IndexType i,
-                                                 const typename Vector::RealType& value,
-                                                 const typename Vector::RealType& thisElementMultiplicator )
+void
+VectorOperations< Devices::Cuda >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value,
+            const typename Vector::RealType& thisElementMultiplicator )
 {
    v[ i ] = thisElementMultiplicator * v[ i ] + value;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Cuda > :: getVectorMax( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Cuda >::
+getVectorMax( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionMax< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Cuda > :: getVectorMin( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Cuda >::
+getVectorMin( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionMin< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Cuda > :: getVectorAbsMax( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Cuda >::
+getVectorAbsMax( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionAbsMax< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Cuda > :: getVectorAbsMin( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Cuda >::
+getVectorAbsMin( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionAbsMin< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
@@ -111,16 +126,16 @@ typename Vector::RealType
 VectorOperations< Devices::Cuda >::
 getVectorL1Norm( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionAbsSum< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
@@ -131,16 +146,16 @@ typename Vector::RealType
 VectorOperations< Devices::Cuda >::
 getVectorL2Norm( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionL2Norm< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return std::sqrt( result );
@@ -153,12 +168,11 @@ VectorOperations< Devices::Cuda >::
 getVectorLpNorm( const Vector& v,
                  const typename Vector::RealType& p )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
-   Assert( p > 0.0,
-              std::cerr << " p = " << p );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_GE( p, 1.0, "Parameter of the L^p norm must be at least 1.0." );
  
    if( p == 1 )
       return getVectorL1Norm( v );
@@ -166,110 +180,120 @@ getVectorLpNorm( const Vector& v,
       return getVectorL2Norm( v );
    Real result( 0 );
    Algorithms::tnlParallelReductionLpNorm< Real, Index > operation;
-   operation. setPower( p );
+   operation.setPower( p );
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return std::pow( result, 1.0 / p );
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Cuda > :: getVectorSum( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Cuda >::
+getVectorSum( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionSum< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v. getSize(),
-                          v. getData(),
+                          v.getSize(),
+                          v.getData(),
                           ( Real* ) 0,
                           result );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getVectorDifferenceMax( const Vector1& v1,
-                                                            const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getVectorDifferenceMax( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffMax< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getVectorDifferenceMin( const Vector1& v1,
-                                                            const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getVectorDifferenceMin( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffMin< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
 
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getVectorDifferenceAbsMax( const Vector1& v1,
-                                                               const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getVectorDifferenceAbsMax( const Vector1& v1,
+                           const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffAbsMax< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getVectorDifferenceAbsMin( const Vector1& v1,
-                                                            const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getVectorDifferenceAbsMin( const Vector1& v1,
+                           const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffAbsMin< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
@@ -280,18 +304,18 @@ VectorOperations< Devices::Cuda >::
 getVectorDifferenceL1Norm( const Vector1& v1,
                            const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffAbsSum< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
@@ -302,18 +326,18 @@ VectorOperations< Devices::Cuda >::
 getVectorDifferenceL2Norm( const Vector1& v1,
                            const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffL2Norm< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return ::sqrt( result );
 }
@@ -324,55 +348,57 @@ typename Vector1::RealType
 VectorOperations< Devices::Cuda >::
 getVectorDifferenceLpNorm( const Vector1& v1,
                            const Vector2& v2,
-                           const typename Vector1 :: RealType& p )
+                           const typename Vector1::RealType& p )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( p > 0.0,
-              std::cerr << " p = " << p );
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
+   TNL_ASSERT_GE( p, 1.0, "Parameter of the L^p norm must be at least 1.0." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffLpNorm< Real, Index > operation;
    operation.setPower( p );
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return ::pow( result, 1.0 / p );
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getVectorDifferenceSum( const Vector1& v1,
-                                                         const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getVectorDifferenceSum( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
    Algorithms::tnlParallelReductionDiffSum< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
 
 #ifdef HAVE_CUDA
 template< typename Real, typename Index >
-__global__ void vectorScalarMultiplicationCudaKernel( Real* data,
-                                                      Index size,
-                                                      Real alpha )
+__global__ void
+vectorScalarMultiplicationCudaKernel( Real* data,
+                                      Index size,
+                                      Real alpha )
 {
-   Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
-   const Index maxGridSize = blockDim. x * gridDim. x;
+   Index elementIdx = blockDim.x * blockIdx.x + threadIdx.x;
+   const Index maxGridSize = blockDim.x * gridDim.x;
    while( elementIdx < size )
    {
       data[ elementIdx ] *= alpha;
@@ -382,39 +408,41 @@ __global__ void vectorScalarMultiplicationCudaKernel( Real* data,
 #endif
 
 template< typename Vector >
-void VectorOperations< Devices::Cuda > :: vectorScalarMultiplication( Vector& v,
-                                                                   const typename Vector::RealType& alpha )
+void
+VectorOperations< Devices::Cuda >::
+vectorScalarMultiplication( Vector& v,
+                            const typename Vector::RealType& alpha )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-
-   Assert( v. getSize() > 0, );
-
-   #ifdef HAVE_CUDA
-      dim3 blockSize( 0 ), gridSize( 0 );
-      const Index& size = v.getSize();
-      blockSize. x = 256;
-      Index blocksNumber = ceil( ( double ) size / ( double ) blockSize. x );
-      gridSize. x = min( blocksNumber, Devices::Cuda::getMaxGridSize() );
-      vectorScalarMultiplicationCudaKernel<<< gridSize, blockSize >>>( v.getData(),
-                                                                       size,
-                                                                       alpha );
-      checkCudaDevice;
-   #else
-      CudaSupportMissingMessage;;
-   #endif
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+
+#ifdef HAVE_CUDA
+   typedef typename Vector::IndexType Index;   
+   dim3 blockSize( 0 ), gridSize( 0 );
+   const Index& size = v.getSize();
+   blockSize.x = 256;
+   Index blocksNumber = ceil( ( double ) size / ( double ) blockSize.x );
+   gridSize.x = min( blocksNumber, Devices::Cuda::getMaxGridSize() );
+   vectorScalarMultiplicationCudaKernel<<< gridSize, blockSize >>>( v.getData(),
+                                                                    size,
+                                                                    alpha );
+   TNL_CHECK_CUDA_DEVICE;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getScalarProduct( const Vector1& v1,
-                                                                                 const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Cuda >::
+getScalarProduct( const Vector1& v1,
+                  const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0 );
 /*#if defined HAVE_CUBLAS && defined HAVE_CUDA
@@ -425,9 +453,9 @@ typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getScalarProdu
 #endif*/
    Algorithms::tnlParallelReductionScalarProduct< Real, Index > operation;
    reductionOnCudaDevice( operation,
-                          v1. getSize(),
-                          v1. getData(),
-                          v2. getData(),
+                          v1.getSize(),
+                          v1.getData(),
+                          v2.getData(),
                           result );
    return result;
 }
@@ -435,14 +463,15 @@ typename Vector1 :: RealType VectorOperations< Devices::Cuda > :: getScalarProdu
 #ifdef HAVE_CUDA
 template< typename Real,
           typename Index >
-__global__ void vectorAddVectorCudaKernel( Real* y,
-                                           const Real* x,
-                                           const Index size,
-                                           const Real alpha,
-                                           const Real thisMultiplicator )
+__global__ void
+vectorAddVectorCudaKernel( Real* y,
+                           const Real* x,
+                           const Index size,
+                           const Real alpha,
+                           const Real thisMultiplicator )
 {
-   Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
-   const Index maxGridSize = blockDim. x * gridDim. x;
+   Index elementIdx = blockDim.x * blockIdx.x + threadIdx.x;
+   const Index maxGridSize = blockDim.x * gridDim.x;
    if( thisMultiplicator == 1.0 )
       while( elementIdx < size )
       {
@@ -455,57 +484,55 @@ __global__ void vectorAddVectorCudaKernel( Real* y,
          y[ elementIdx ] = thisMultiplicator * y[ elementIdx ] + alpha * x[ elementIdx ];
          elementIdx += maxGridSize;
       }
-
 }
 #endif
 
 template< typename Vector1, typename Vector2 >
-void VectorOperations< Devices::Cuda > :: addVector( Vector1& y,
-                                                  const Vector2& x,
-                                                  const typename Vector2::RealType& alpha,
-                                                  const typename Vector1::RealType& thisMultiplicator )
+void
+VectorOperations< Devices::Cuda >::
+addVector( Vector1& y,
+           const Vector2& x,
+           const typename Vector2::RealType& alpha,
+           const typename Vector1::RealType& thisMultiplicator )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
-
-   Assert( y. getSize() > 0, );
-   Assert( y. getSize() == x. getSize(), );
-   Assert( y.getData() != 0, );
-   Assert( x.getData() != 0, );
-
-
-   #ifdef HAVE_CUDA
-      dim3 blockSize( 0 ), gridSize( 0 );
-
-      const Index& size = x.getSize();
-      dim3 cudaBlockSize( 256 );
-      dim3 cudaBlocks;
-      cudaBlocks.x = min( Devices::Cuda::getMaxGridSize(), Devices::Cuda::getNumberOfBlocks( size, cudaBlockSize.x ) );
-
-      vectorAddVectorCudaKernel<<< cudaBlocks, cudaBlockSize >>>( y.getData(),
-                                                                  x.getData(),
-                                                                  size,
-                                                                  alpha,
-                                                                  thisMultiplicator);
-      checkCudaDevice;
-   #else
-      CudaSupportMissingMessage;;
-   #endif
+   TNL_ASSERT_GT( x.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( x.getSize(), y.getSize(), "The vector sizes must be the same." );
+
+#ifdef HAVE_CUDA
+   typedef typename Vector1::IndexType Index;
+   
+   dim3 blockSize( 0 ), gridSize( 0 );
+
+   const Index& size = x.getSize();
+   dim3 cudaBlockSize( 256 );
+   dim3 cudaBlocks;
+   cudaBlocks.x = min( Devices::Cuda::getMaxGridSize(), Devices::Cuda::getNumberOfBlocks( size, cudaBlockSize.x ) );
+
+   vectorAddVectorCudaKernel<<< cudaBlocks, cudaBlockSize >>>( y.getData(),
+                                                               x.getData(),
+                                                               size,
+                                                               alpha,
+                                                               thisMultiplicator);
+   TNL_CHECK_CUDA_DEVICE;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 #ifdef HAVE_CUDA
 template< typename Real,
           typename Index >
-__global__ void vectorAddVectorsCudaKernel( Real* v,
-                                            const Real* v1,
-                                            const Real* v2,
-                                            const Index size,
-                                            const Real multiplicator1,
-                                            const Real multiplicator2,
-                                            const Real thisMultiplicator )
+__global__ void
+vectorAddVectorsCudaKernel( Real* v,
+                            const Real* v1,
+                            const Real* v2,
+                            const Index size,
+                            const Real multiplicator1,
+                            const Real multiplicator2,
+                            const Real thisMultiplicator )
 {
-   Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
-   const Index maxGridSize = blockDim. x * gridDim. x;
+   Index elementIdx = blockDim.x * blockIdx.x + threadIdx.x;
+   const Index maxGridSize = blockDim.x * gridDim.x;
    if( thisMultiplicator == 1.0 )
       while( elementIdx < size )
       {
@@ -524,7 +551,6 @@ __global__ void vectorAddVectorsCudaKernel( Real* v,
 }
 #endif
 
-
 template< typename Vector1,
           typename Vector2,
           typename Vector3 >
@@ -537,84 +563,81 @@ addVectors( Vector1& v,
             const typename Vector3::RealType& multiplicator2,
             const typename Vector1::RealType& thisMultiplicator )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
-
-   Assert( v.getSize() > 0, );
-   Assert( v.getSize() == v1.getSize(), );
-   Assert( v.getSize() == v2.getSize(), );
-   Assert( v.getData() != 0, );
-   Assert( v1.getData() != 0, );
-   Assert( v2.getData() != 0, );
-
-   #ifdef HAVE_CUDA
-      dim3 blockSize( 0 ), gridSize( 0 );
-
-      const Index& size = v.getSize();
-      dim3 cudaBlockSize( 256 );
-      dim3 cudaBlocks;
-      cudaBlocks.x = min( Devices::Cuda::getMaxGridSize(), Devices::Cuda::getNumberOfBlocks( size, cudaBlockSize.x ) );
-
-      vectorAddVectorsCudaKernel<<< cudaBlocks, cudaBlockSize >>>( v.getData(),
-                                                                   v1.getData(),
-                                                                   v2.getData(),
-                                                                   size,
-                                                                   multiplicator1,
-                                                                   multiplicator2,
-                                                                   thisMultiplicator);
-      checkCudaDevice;
-   #else
-      CudaSupportMissingMessage;;
-   #endif
-
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v.getSize(), v1.getSize(), "The vector sizes must be the same." );
+   TNL_ASSERT_EQ( v.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
+#ifdef HAVE_CUDA
+   typedef typename Vector1::IndexType Index;   
+   dim3 blockSize( 0 ), gridSize( 0 );
+
+   const Index& size = v.getSize();
+   dim3 cudaBlockSize( 256 );
+   dim3 cudaBlocks;
+   cudaBlocks.x = min( Devices::Cuda::getMaxGridSize(), Devices::Cuda::getNumberOfBlocks( size, cudaBlockSize.x ) );
+
+   vectorAddVectorsCudaKernel<<< cudaBlocks, cudaBlockSize >>>( v.getData(),
+                                                                v1.getData(),
+                                                                v2.getData(),
+                                                                size,
+                                                                multiplicator1,
+                                                                multiplicator2,
+                                                                thisMultiplicator);
+   TNL_CHECK_CUDA_DEVICE;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Cuda >::computePrefixSum( Vector& v,
-                                                       typename Vector::IndexType begin,
-                                                       typename Vector::IndexType end )
+void
+VectorOperations< Devices::Cuda >::
+computePrefixSum( Vector& v,
+                  typename Vector::IndexType begin,
+                  typename Vector::IndexType end )
 {
-   #ifdef HAVE_CUDA
-   typedef Algorithms::tnlParallelReductionSum< typename Vector::RealType,
-                                    typename Vector::IndexType > OperationType;
+#ifdef HAVE_CUDA
+   typedef Algorithms::tnlParallelReductionSum< typename Vector::RealType, typename Vector::IndexType > OperationType;
 
    OperationType operation;
    Algorithms::cudaPrefixSum< typename Vector::RealType,
-                  OperationType,
-                  typename Vector::IndexType >( end - begin,
-                                                256,
-                                                &v.getData()[ begin ],
-                                                &v.getData()[ begin ],
-                                                operation,
-                                                Algorithms::inclusivePrefixSum );
-   #else
-      CudaSupportMissingMessage;;
-   #endif
+                              OperationType,
+                              typename Vector::IndexType >
+                                 ( end - begin,
+                                   256,
+                                   &v.getData()[ begin ],
+                                   &v.getData()[ begin ],
+                                   operation,
+                                   Algorithms::PrefixSumType::inclusive );
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Cuda >::computeExclusivePrefixSum( Vector& v,
-                                                                typename Vector::IndexType begin,
-                                                                typename Vector::IndexType end )
+void
+VectorOperations< Devices::Cuda >::
+computeExclusivePrefixSum( Vector& v,
+                           typename Vector::IndexType begin,
+                           typename Vector::IndexType end )
 {
 #ifdef HAVE_CUDA
-   typedef Algorithms::tnlParallelReductionSum< typename Vector::RealType,
-                                    typename Vector::IndexType > OperationType;
+   typedef Algorithms::tnlParallelReductionSum< typename Vector::RealType, typename Vector::IndexType > OperationType;
 
    OperationType operation;
-
    Algorithms::cudaPrefixSum< typename Vector::RealType,
-                  OperationType,
-                  typename Vector::IndexType >( end - begin,
-                                                256,
-                                                &v.getData()[ begin ],
-                                                &v.getData()[ begin ],
-                                                operation,
-                                                Algorithms::exclusivePrefixSum );
+                              OperationType,
+                              typename Vector::IndexType >
+                                 ( end - begin,
+                                   256,
+                                   &v.getData()[ begin ],
+                                   &v.getData()[ begin ],
+                                   operation,
+                                   Algorithms::PrefixSumType::exclusive );
 #endif
 }
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
 
@@ -624,6 +647,7 @@ void VectorOperations< Devices::Cuda >::computeExclusivePrefixSum( Vector& v,
 
 namespace TNL {
 namespace Containers {
+namespace Algorithms {
 
 /****
  * Max
@@ -875,6 +899,7 @@ extern template long double VectorOperations< Devices::Cuda >::getVectorDifferen
 #endif
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
 
diff --git a/src/TNL/Containers/VectorOperationsHost_impl.h b/src/TNL/Containers/Algorithms/VectorOperationsHost_impl.h
similarity index 72%
rename from src/TNL/Containers/VectorOperationsHost_impl.h
rename to src/TNL/Containers/Algorithms/VectorOperationsHost_impl.h
index 102cc083d9db6959297e1c6dc6a3fc72a28c06e8..d8cbca17eae6398235a165455872d7c9284dacd9 100644
--- a/src/TNL/Containers/VectorOperationsHost_impl.h
+++ b/src/TNL/Containers/Algorithms/VectorOperationsHost_impl.h
@@ -10,79 +10,114 @@
 
 #pragma once 
 
+#include <TNL/Containers/Algorithms/VectorOperations.h>
+
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
-static const int OpenMPVectorOperationsThreshold = 65536; // TODO: check this threshold
+static const int OpenMPVectorOperationsThreshold = 512; // TODO: check this threshold
 static const int PrefetchDistance = 128;
 
 template< typename Vector >
-void VectorOperations< Devices::Host >::addElement( Vector& v,
-                                                 const typename Vector::IndexType i,
-                                                 const typename Vector::RealType& value )
+void
+VectorOperations< Devices::Host >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value )
 {
    v[ i ] += value;
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Host >::addElement( Vector& v,
-                                                 const typename Vector::IndexType i,
-                                                 const typename Vector::RealType& value,
-                                                 const typename Vector::RealType& thisElementMultiplicator )
+void
+VectorOperations< Devices::Host >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value,
+            const typename Vector::RealType& thisElementMultiplicator )
 {
    v[ i ] = thisElementMultiplicator * v[ i ] + value;
 }
 
 template< typename Vector >
-typename Vector::RealType VectorOperations< Devices::Host >::getVectorMax( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Host >::
+getVectorMax( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
-   Real result = v. getElement( 0 );
-   const Index n = v. getSize();
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+
+   Real result = v.getElement( 0 );
+   const Index n = v.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(max:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result = max( result, v. getElement( i ) );
+      result = max( result, v.getElement( i ) );
    return result;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Host > :: getVectorMin( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Host >::
+getVectorMin( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
-   Real result = v. getElement( 0 );
-   const Index n = v. getSize();
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+
+   Real result = v.getElement( 0 );
+   const Index n = v.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(min:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result = min( result, v. getElement( i ) );
+      result = min( result, v.getElement( i ) );
    return result;
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Host > :: getVectorAbsMax( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Host >::
+getVectorAbsMax( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
-   Real result = std::fabs( v. getElement( 0 ) );
-   const Index n = v. getSize();
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+
+   Real result = std::fabs( v.getElement( 0 ) );
+   const Index n = v.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(max:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result = max( result, ( Real ) std::fabs( v. getElement( i ) ) );
+      result = max( result, ( Real ) std::fabs( v.getElement( i ) ) );
    return result;
 }
 
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Host > :: getVectorAbsMin( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Host >::
+getVectorAbsMin( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
-   Real result = std::fabs( v. getElement( 0 ) );
-   const Index n = v. getSize();
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+
+   Real result = std::fabs( v.getElement( 0 ) );
+   const Index n = v.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(min:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result = min( result, ( Real ) std::fabs( v. getElement( i ) ) );
+      result = min( result, ( Real ) std::fabs( v.getElement( i ) ) );
    return result;
 }
 
@@ -91,12 +126,13 @@ typename Vector::RealType
 VectorOperations< Devices::Host >::
 getVectorL1Norm( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0.0 );
-   const Index n = v. getSize();
+   const Index n = v.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -110,11 +146,12 @@ typename Vector::RealType
 VectorOperations< Devices::Host >::
 getVectorL2Norm( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
-   Assert( v. getSize() > 0, );
-   const Index n = v. getSize();
+   const Index n = v.getSize();
 
 #ifdef OPTIMIZED_VECTOR_HOST_OPERATIONS
 #ifdef __GNUC__
@@ -170,20 +207,21 @@ template< typename Vector >
 typename Vector::RealType
 VectorOperations< Devices::Host >::
 getVectorLpNorm( const Vector& v,
-                 const typename Vector :: RealType& p )
+                 const typename Vector::RealType& p )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
-   Assert( p > 0.0,
-              std::cerr << " p = " << p );
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_GE( p, 1.0, "Parameter of the L^p norm must be at least 1.0." );
+
    if( p == 1.0 )
       return getVectorL1Norm( v );
    if( p == 2.0 )
       return getVectorL2Norm( v );
 
    Real result( 0.0 );
-   const Index n = v. getSize();
+   const Index n = v.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -193,14 +231,17 @@ getVectorLpNorm( const Vector& v,
 }
 
 template< typename Vector >
-typename Vector :: RealType VectorOperations< Devices::Host > :: getVectorSum( const Vector& v )
+typename Vector::RealType
+VectorOperations< Devices::Host >::
+getVectorSum( const Vector& v )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
-   Assert( v. getSize() > 0, );
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
    Real result( 0.0 );
-   const Index n = v. getSize();
+   const Index n = v.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -210,66 +251,88 @@ typename Vector :: RealType VectorOperations< Devices::Host > :: getVectorSum( c
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Host > :: getVectorDifferenceMax( const Vector1& v1,
-                                                                                       const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getVectorDifferenceMax( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
-   Real result = v1. getElement( 0 ) - v2. getElement( 0 );
-   const Index n = v1. getSize();
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
+
+   Real result = v1.getElement( 0 ) - v2.getElement( 0 );
+   const Index n = v1.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(max:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result =  max( result, v1. getElement( i ) - v2. getElement( i ) );
+      result =  max( result, v1.getElement( i ) - v2.getElement( i ) );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Host > :: getVectorDifferenceMin( const Vector1& v1,
-                                                                                       const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getVectorDifferenceMin( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
-   Real result = v1. getElement( 0 ) - v2. getElement( 0 );
-   const Index n = v1. getSize();
+   Real result = v1.getElement( 0 ) - v2.getElement( 0 );
+   const Index n = v1.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(min:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result =  min( result, v1. getElement( i ) - v2. getElement( i ) );
+      result =  min( result, v1.getElement( i ) - v2.getElement( i ) );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Host > :: getVectorDifferenceAbsMax( const Vector1& v1,
-                                                                                          const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getVectorDifferenceAbsMax( const Vector1& v1,
+                           const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
-   Real result = std::fabs( v1. getElement( 0 ) - v2. getElement( 0 ) );
-   const Index n = v1. getSize();
+   Real result = std::fabs( v1.getElement( 0 ) - v2.getElement( 0 ) );
+   const Index n = v1.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(max:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
-      result =  max( result, ( Real ) std::fabs( v1. getElement( i ) - v2. getElement( i ) ) );
+      result =  max( result, ( Real ) std::fabs( v1.getElement( i ) - v2.getElement( i ) ) );
    return result;
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Host > :: getVectorDifferenceAbsMin( const Vector1& v1,
-                                                                                          const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getVectorDifferenceAbsMin( const Vector1& v1,
+                           const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result = std::fabs( v1[ 0 ] - v2[ 0 ] );
-   const Index n = v1. getSize();
+   const Index n = v1.getSize();
+#if defined( HAVE_OPENMP ) && _OPENMP >= 201107  // OpenMP 3.1 added support for min/max reduction operations
+#pragma omp parallel for reduction(min:result) if( TNL::Devices::Host::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#endif
    for( Index i = 1; i < n; i ++ )
       result =  min( result, ( Real ) std::fabs( v1[ i ] - v2[ i ] ) );
    return result;
@@ -281,14 +344,14 @@ VectorOperations< Devices::Host >::
 getVectorDifferenceL1Norm( const Vector1& v1,
                            const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0.0 );
-   const Index n = v1. getSize();
+   const Index n = v1.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -303,14 +366,14 @@ VectorOperations< Devices::Host >::
 getVectorDifferenceL2Norm( const Vector1& v1,
                            const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0.0 );
-   const Index n = v1. getSize();
+   const Index n = v1.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -330,13 +393,12 @@ getVectorDifferenceLpNorm( const Vector1& v1,
                            const Vector2& v2,
                            const typename Vector1::RealType& p )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( p > 0.0,
-              std::cerr << " p = " << p );
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
+   TNL_ASSERT_GE( p, 1.0, "Parameter of the L^p norm must be at least 1.0." );
 
    if( p == 1.0 )
       return getVectorDifferenceL1Norm( v1, v2 );
@@ -344,46 +406,49 @@ getVectorDifferenceLpNorm( const Vector1& v1,
       return getVectorDifferenceL2Norm( v1, v2 );
 
    Real result( 0.0 );
-   const Index n = v1. getSize();
+   const Index n = v1.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
    for( Index i = 0; i < n; i ++ )
-      result += std::pow( std::fabs( v1. getElement( i ) - v2. getElement( i ) ), p );
+      result += std::pow( std::fabs( v1.getElement( i ) - v2.getElement( i ) ), p );
    return std::pow( result, 1.0 / p );
 }
 
 template< typename Vector1, typename Vector2 >
-typename Vector1::RealType VectorOperations< Devices::Host > :: getVectorDifferenceSum( const Vector1& v1,
-                                                                                     const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getVectorDifferenceSum( const Vector1& v1,
+                        const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
 
    Real result( 0.0 );
-   const Index n = v1. getSize();
+   const Index n = v1.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for reduction(+:result) if( TNL::Devices::Host::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
    for( Index i = 0; i < n; i ++ )
-      result += v1. getElement( i ) - v2. getElement( i );
+      result += v1.getElement( i ) - v2.getElement( i );
    return result;
 }
 
 
 template< typename Vector >
-void VectorOperations< Devices::Host > :: vectorScalarMultiplication( Vector& v,
-                                                                   const typename Vector :: RealType& alpha )
+void
+VectorOperations< Devices::Host >::
+vectorScalarMultiplication( Vector& v,
+                            const typename Vector::RealType& alpha )
 {
-   typedef typename Vector :: RealType Real;
-   typedef typename Vector :: IndexType Index;
+   typedef typename Vector::IndexType Index;
 
-   Assert( v. getSize() > 0, );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
 
-   const Index n = v. getSize();
+   const Index n = v.getSize();
 #ifdef HAVE_OPENMP
 #pragma omp parallel for if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif
@@ -393,15 +458,17 @@ void VectorOperations< Devices::Host > :: vectorScalarMultiplication( Vector& v,
 
 
 template< typename Vector1, typename Vector2 >
-typename Vector1 :: RealType VectorOperations< Devices::Host > :: getScalarProduct( const Vector1& v1,
-                                                                                 const Vector2& v2 )
+typename Vector1::RealType
+VectorOperations< Devices::Host >::
+getScalarProduct( const Vector1& v1,
+                  const Vector2& v2 )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v1. getSize() > 0, );
-   Assert( v1. getSize() == v2. getSize(), );
-   const Index n = v1. getSize();
+   TNL_ASSERT_GT( v1.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v1.getSize(), v2.getSize(), "The vector sizes must be the same." );
+   const Index n = v1.getSize();
 
 #ifdef OPTIMIZED_VECTOR_HOST_OPERATIONS
 #ifdef __GNUC__
@@ -453,22 +520,25 @@ typename Vector1 :: RealType VectorOperations< Devices::Host > :: getScalarProdu
 }
 
 template< typename Vector1, typename Vector2 >
-void VectorOperations< Devices::Host > :: addVector( Vector1& y,
-                                                  const Vector2& x,
-                                                  const typename Vector2::RealType& alpha,
-                                                  const typename Vector1::RealType& thisMultiplicator )
+void
+VectorOperations< Devices::Host >::
+addVector( Vector1& y,
+           const Vector2& x,
+           const typename Vector2::RealType& alpha,
+           const typename Vector1::RealType& thisMultiplicator )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( x. getSize() > 0, );
-   Assert( x. getSize() == y. getSize(), );
-   const Index n = y. getSize();
+   TNL_ASSERT_GT( x.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( x.getSize(), y.getSize(), "The vector sizes must be the same." );
+
+   const Index n = y.getSize();
 
 #ifdef OPTIMIZED_VECTOR_HOST_OPERATIONS
 #ifdef __GNUC__
    // We need to get the address of the first element to avoid
    // bounds checking in TNL::Array::operator[]
+   typedef typename Vector1::RealType Real;   
          Real* Y = y.getData();
    const Real* X = x.getData();
 #endif
@@ -527,12 +597,11 @@ addVectors( Vector1& v,
             const typename Vector3::RealType& multiplicator2,
             const typename Vector1::RealType& thisMultiplicator )
 {
-   typedef typename Vector1 :: RealType Real;
-   typedef typename Vector1 :: IndexType Index;
+   typedef typename Vector1::IndexType Index;
 
-   Assert( v.getSize() > 0, );
-   Assert( v.getSize() == v1.getSize(), );
-   Assert( v.getSize() == v2.getSize(), );
+   TNL_ASSERT_GT( v.getSize(), 0, "Vector size must be positive." );
+   TNL_ASSERT_EQ( v.getSize(), v1.getSize(), "The vector sizes must be the same." );
+   TNL_ASSERT_EQ( v.getSize(), v2.getSize(), "The vector sizes must be the same." );
  
    const Index n = v.getSize();
    if( thisMultiplicator == 1.0 )
@@ -550,22 +619,30 @@ addVectors( Vector1& v,
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Host >::computePrefixSum( Vector& v,
-                                                       typename Vector::IndexType begin,
-                                                       typename Vector::IndexType end )
+void
+VectorOperations< Devices::Host >::
+computePrefixSum( Vector& v,
+                  typename Vector::IndexType begin,
+                  typename Vector::IndexType end )
 {
    typedef typename Vector::IndexType Index;
+
+   // TODO: parallelize with OpenMP
    for( Index i = begin + 1; i < end; i++ )
       v[ i ] += v[ i - 1 ];
 }
 
 template< typename Vector >
-void VectorOperations< Devices::Host >::computeExclusivePrefixSum( Vector& v,
-                                                                typename Vector::IndexType begin,
-                                                                typename Vector::IndexType end )
+void
+VectorOperations< Devices::Host >::
+computeExclusivePrefixSum( Vector& v,
+                           typename Vector::IndexType begin,
+                           typename Vector::IndexType end )
 {
    typedef typename Vector::IndexType Index;
    typedef typename Vector::RealType Real;
+
+   // TODO: parallelize with OpenMP
    Real aux( v[ begin ] );
    v[ begin ] = 0.0;
    for( Index i = begin + 1; i < end; i++ )
@@ -576,8 +653,9 @@ void VectorOperations< Devices::Host >::computeExclusivePrefixSum( Vector& v,
    }
 }
 
+} // namespace Algorithms
 } // namespace Containers
-} //namespace TNL
+} // namespace TNL
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -585,6 +663,7 @@ void VectorOperations< Devices::Host >::computeExclusivePrefixSum( Vector& v,
 
 namespace TNL {
 namespace Containers {   
+namespace Algorithms {
 
 /****
  * Max
@@ -837,8 +916,8 @@ extern template long double VectorOperations< Devices::Host >::getVectorDifferen
 #endif
 #endif
 
+} // namespace Algorithms
 } // namespace Containers
 } // namespace TNL
-#endif
-
 
+#endif
diff --git a/src/TNL/Containers/Algorithms/VectorOperationsMIC_impl.h b/src/TNL/Containers/Algorithms/VectorOperationsMIC_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae462d7a8b7d5c7a425e243543f90b8c4444d03b
--- /dev/null
+++ b/src/TNL/Containers/Algorithms/VectorOperationsMIC_impl.h
@@ -0,0 +1,669 @@
+/***************************************************************************
+                          VectorOperationsMIC_impl.h  -  description
+                                by hanouvit
+                          -------------------
+    begin                : Nov 7, 2012
+    copyright            : (C) 2012 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+
+#pragma once
+
+#include <TNL/Devices/MIC.h>
+#include <TNL/Math.h>
+
+namespace TNL {
+namespace Containers {
+namespace Algorithms {
+
+//static const int OpenMPVectorOperationsThreshold = 65536; // TODO: check this threshold
+
+template< typename Vector >
+void
+VectorOperations< Devices::MIC >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value )
+{
+   // v[ i ] += value;
+   //cout << "Errorous function, not clear wher should be called (device or Host)" << endl;
+   v.setElement(i,v.getElemet(i)+value);
+}
+
+template< typename Vector >
+void
+VectorOperations< Devices::MIC >::
+addElement( Vector& v,
+            const typename Vector::IndexType i,
+            const typename Vector::RealType& value,
+            const typename Vector::RealType& thisElementMultiplicator )
+{
+   //v[ i ] = thisElementMultiplicator * v[ i ] + value;
+   //cout << "Errorous function, not clear wher should be called (device or Host)" << endl;
+   v.setElement(i,thisElementMultiplicator*v.getElemet(i)+value);
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorMax( const Vector& v )
+{
+   //tady je moĹľnost paralelizace
+   typename Vector::RealType result;
+   typename Vector::IndexType size=v.getSize();
+   Devices::MICHider<const typename Vector::RealType > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,size) out(result)
+   {
+      result=vct.pointer[0];
+      for(typename Vector::IndexType i=1;i<size;i++)
+      {
+         if(result<vct.pointer[i])
+            result=vct.pointer[i];
+      }
+   }
+   return result;
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorMin( const Vector& v )
+{
+   //tady je moĹľnost paralelizace
+   typename Vector::RealType result;
+   typename Vector::IndexType size=v.getSize();
+   Devices::MICHider<const typename Vector::RealType > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,size) out(result)
+   {
+      result=vct.pointer[0];
+      for(typename Vector::IndexType i=1;i<size;i++)
+      {
+         if(result>vct.pointer[i])
+            result=vct.pointer[i];
+      }
+   }
+   return result;
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorAbsMax( const Vector& v )
+{
+   //tady je moĹľnost paralelizace
+   typename Vector::RealType result;
+   typename Vector::IndexType size=v.getSize();
+   Devices::MICHider<const typename Vector::RealType > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,size) out(result)
+   {
+      result=TNL::abs(vct.pointer[0]);
+      for(typename Vector::IndexType i=1;i<size;i++)
+      {
+         if(result<TNL::abs(vct.pointer[i]))
+            result=TNL::abs(vct.pointer[i]);
+      }
+   }
+   return result;
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorAbsMin( const Vector& v )
+{
+   //tady je moĹľnost paralelizace
+   typename Vector::RealType result;
+   typename Vector::IndexType size=v.getSize();
+   Devices::MICHider<const typename Vector::RealType > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,size) out(result)
+   {
+      result=TNL::abs(vct.pointer[0]);
+      for(typename Vector::IndexType i=1;i<size;i++)
+      {
+         if(result>TNL::abs(vct.pointer[i]))
+            result=TNL::abs(vct.pointer[i]);
+      }
+   }
+   return result;
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorL1Norm( const Vector& v )
+{
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+   TNL_ASSERT( v. getSize() > 0, );
+
+   Real result( 0.0 );
+   const Index n = v. getSize();
+   Devices::MICHider<const Real > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,n) inout(result)
+   {
+      #pragma omp parallel for reduction(+:result)// if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+      for( Index i = 0; i < n; i ++ )
+         result += TNL::abs( vct.pointer[ i ] );
+   }
+   return result;
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorL2Norm( const Vector& v )
+{
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+   TNL_ASSERT( v. getSize() > 0, );
+   Real result( 0.0 );
+   const Index n = v. getSize();
+   Devices::MICHider<const Real > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,n) inout(result)
+   {
+      #pragma omp parallel for reduction(+:result) //if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+      for( Index i = 0; i < n; i ++ )
+      {
+         const Real& aux = vct.pointer[ i ];
+         result += aux * aux;
+      }
+   }
+   return TNL::sqrt( result );
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorLpNorm( const Vector& v,
+                 const typename Vector::RealType& p )
+{
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+   TNL_ASSERT( v. getSize() > 0, );
+   TNL_ASSERT( p > 0.0,
+               std::cerr << " p = " << p );
+   if( p == 1.0 )
+      return getVectorL1Norm( v );
+   if( p == 2.0 )
+      return getVectorL2Norm( v );
+
+   Real result( 0.0 );
+   const Index n = v. getSize();
+   Devices::MICHider<const Real > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,n) inout(result)
+   {
+      #pragma omp parallel for reduction(+:result) //if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+      for( Index i = 0; i < n; i ++ )
+      {
+         result += TNL::pow( TNL::abs( vct.pointer[ i ] ), p );
+      }
+   }
+   return TNL::pow( result, 1.0 / p );
+}
+
+template< typename Vector >
+typename Vector::RealType
+VectorOperations< Devices::MIC >::
+getVectorSum( const Vector& v )
+{
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+   TNL_ASSERT( v. getSize() > 0, );
+
+   Real result( 0.0 );
+   const Index n = v. getSize();
+   Devices::MICHider<const Real > vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,n) inout(result)
+   {
+      #pragma omp parallel for reduction(+:result)// if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+      for( Index i = 0; i < n; i ++ )
+         result += vct.pointer[ i ] ;
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC>::
+getVectorDifferenceMax( const Vector1& v1,
+                        const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) out(result)
+   {
+      result = vct1.pointer[0] - vct2.pointer[0];
+      for( Index i = 1; i < n; i ++ )
+         result = TNL::max( result, vct1.pointer[ i ] - vct2.pointer[ i ] );
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceMin( const Vector1& v1,
+                        const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) out(result)
+   {
+      result = vct1.pointer[0] - vct2.pointer[0];
+      for( Index i = 1; i < n; i ++ )
+         result = TNL::min( result, vct1.pointer[ i ] - vct2.pointer[ i ] );
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceAbsMax( const Vector1& v1,
+                           const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) out(result)
+   {
+      result = TNL::abs(vct1.pointer[0] - vct2.pointer[0]);
+      for( Index i = 1; i < n; i ++ )
+         result = TNL::max( result, TNL::abs(vct1.pointer[ i ] - vct2.pointer[ i ]) );
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceAbsMin( const Vector1& v1,
+                           const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) out(result)
+   {
+      result = TNL::abs(vct1.pointer[0] - vct2.pointer[0]);
+      for( Index i = 1; i < n; i ++ )
+         result = TNL::min( result, TNL::abs(vct1.pointer[ i ] - vct2.pointer[ i ]) );
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceL1Norm( const Vector1& v1,
+                           const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real> vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) inout(result)
+   {
+      for( Index i = 0; i < n; i ++ )
+         result += TNL::abs( vct1.pointer[ i ] - vct2.pointer[ i ] );
+   }
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceL2Norm( const Vector1& v1,
+                           const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) inout(result)
+   {
+      for( Index i = 0; i < n; i ++ )
+      {
+         Real aux = TNL::abs( vct1.pointer[ i ] - vct2.pointer[ i ] );
+         result += aux * aux;
+      }
+   }
+
+   return TNL::sqrt( result );
+}
+
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceLpNorm( const Vector1& v1,
+                           const Vector2& v2,
+                           const typename Vector1::RealType& p )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+
+   TNL_ASSERT( p > 0.0,
+              std::cerr << " p = " << p );
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   if( p == 1.0 )
+      return getVectorDifferenceL1Norm( v1, v2 );
+   if( p == 2.0 )
+      return getVectorDifferenceL2Norm( v1, v2 );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) inout(result)
+   {
+      for( Index i = 0; i < n; i ++ )
+      {
+         result += TNL::pow( TNL::abs( vct1.pointer[ i ] - vct2.pointer[ i ] ), p );
+      }
+   }
+   return TNL::pow( result, 1.0 / p );
+}
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getVectorDifferenceSum( const Vector1& v1,
+                        const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(n,vct1,vct2) inout(result)
+   {
+      for( Index i = 0; i < n; i ++ )
+         result +=  vct1.pointer[ i ] - vct2.pointer[ i ];
+   }
+   return result;
+}
+
+
+template< typename Vector >
+void
+VectorOperations< Devices::MIC >::
+vectorScalarMultiplication( Vector& v,
+                            const typename Vector::RealType& alpha )
+{
+   typedef typename Vector::RealType Real;
+   typedef typename Vector::IndexType Index;
+
+   TNL_ASSERT( v. getSize() > 0, );
+
+   const Index n = v. getSize();
+   Devices::MICHider<Real > vct;
+   vct.pointer=v.getData();
+   Real a=alpha;
+
+   #pragma offload target(mic) in(vct,a,n)
+   {
+      for( Index i = 0; i < n; i ++ )
+         vct.pointer[ i ] *= a;
+   }
+}
+
+
+template< typename Vector1, typename Vector2 >
+typename Vector1::RealType
+VectorOperations< Devices::MIC >::
+getScalarProduct( const Vector1& v1,
+                  const Vector2& v2 )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v1. getSize() > 0, );
+   TNL_ASSERT( v1. getSize() == v2. getSize(), );
+
+   Real result( 0.0 );
+   const Index n = v1. getSize();
+   Devices::MICHider<const Real > vct1;
+   Devices::MICHider<const Real > vct2;
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+
+   #pragma offload target(mic) in(vct1,vct2,n) inout(result)
+   {
+      #pragma omp parallel for reduction(+:result)// if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+      for( Index i = 0; i < n; i++ )
+         result += vct1.pointer[ i ] * vct2.pointer[ i ];
+   }
+   /*Real result1( 0.0 ), result2( 0.0 ), result3( 0.0 ), result4( 0.0 ),
+        result5( 0.0 ), result6( 0.0 ), result7( 0.0 ), result8( 0.0 );
+   Index i( 0 );
+   while( i + 8 < n )
+   {
+      result1 += v1[ i ] * v2[ i ];
+      result2 += v1[ i + 1 ] * v2[ i + 1 ];
+      result3 += v1[ i + 2 ] * v2[ i + 2 ];
+      result4 += v1[ i + 3 ] * v2[ i + 3 ];
+      result5 += v1[ i + 4 ] * v2[ i + 4 ];
+      result6 += v1[ i + 5 ] * v2[ i + 5 ];
+      result7 += v1[ i + 6 ] * v2[ i + 6 ];
+      result8 += v1[ i + 7 ] * v2[ i + 7 ];
+      i += 8;
+   }
+   Real result = result1 + result2 + result3 + result4 + result5 +result6 +result7 +result8;
+   while( i < n )
+      result += v1[ i ] * v2[ i++ ];*/
+   return result;
+}
+
+template< typename Vector1, typename Vector2 >
+void
+VectorOperations< Devices::MIC >::
+addVector( Vector1& y,
+           const Vector2& x,
+           const typename Vector2::RealType& alpha,
+           const typename Vector1::RealType& thisMultiplicator )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( x. getSize() > 0, );
+   TNL_ASSERT( x. getSize() == y. getSize(), );
+
+   const Index n = y. getSize();
+   Devices::MICHider<Real> vct;
+   Devices::MICHider<const Real> vct2;
+   vct.pointer=y.getData();
+   vct2.pointer=x.getData();
+   Real a=alpha;
+   Real t=thisMultiplicator;
+
+   #pragma offload target(mic) in(vct,vct2,n,a,t)
+   {
+      for( Index i = 0; i < n; i ++ )
+         vct.pointer[ i ] = t * vct.pointer[ i ] + a * vct2.pointer[ i ];
+   }
+}
+
+template< typename Vector1,
+          typename Vector2,
+          typename Vector3 >
+void
+VectorOperations< Devices::MIC >::
+addVectors( Vector1& v,
+            const Vector2& v1,
+            const typename Vector2::RealType& multiplicator1,
+            const Vector3& v2,
+            const typename Vector3::RealType& multiplicator2,
+            const typename Vector1::RealType& thisMultiplicator )
+{
+   typedef typename Vector1::RealType Real;
+   typedef typename Vector1::IndexType Index;
+   TNL_ASSERT( v.getSize() > 0, );
+   TNL_ASSERT( v.getSize() == v1.getSize(), );
+   TNL_ASSERT( v.getSize() == v2.getSize(), );
+
+   const Index n = v. getSize();
+   Devices::MICHider<Real> vct;
+   Devices::MICHider<const Real> vct1;
+   Devices::MICHider<const Real> vct2;
+   vct.pointer=v.getData();
+   vct1.pointer=v1.getData();
+   vct2.pointer=v2.getData();
+   Real t=thisMultiplicator;
+   Real m1=multiplicator1;
+   Real m2=multiplicator2;
+
+   #pragma offload target(mic) in(vct,vct1,vct2,n,t,m1,m2)
+   {
+      for( Index i = 0; i < n; i ++ )
+         vct.pointer[ i ] = t * vct.pointer[ i ] + m1 * vct1.pointer[ i ] + m2 * vct2.pointer[ i ];
+   }
+}
+
+template< typename Vector >
+void
+VectorOperations< Devices::MIC >::
+computePrefixSum( Vector& v,
+                  typename Vector::IndexType begin,
+                  typename Vector::IndexType end )
+{
+   typedef typename Vector::IndexType Index;
+
+   //std::cout << v.getSize()<< "    " << end <<endl;
+
+   TNL_ASSERT( v.getSize() > 0, );
+   TNL_ASSERT( v.getSize() >= end, );
+   TNL_ASSERT( v.getSize() > begin, );
+   TNL_ASSERT( end > begin, );
+
+   Devices::MICHider<typename Vector::RealType> vct;
+   vct.pointer=v.getData();
+   #pragma offload target(mic) in(vct,begin,end)
+   {
+      for( Index i = begin + 1; i < end; i++ )
+         vct.pointer[ i ] += vct.pointer[ i - 1 ];
+   }
+}
+
+template< typename Vector >
+void
+VectorOperations< Devices::MIC >::
+computeExclusivePrefixSum( Vector& v,
+                           typename Vector::IndexType begin,
+                           typename Vector::IndexType end )
+{
+   typedef typename Vector::IndexType Index;
+   typedef typename Vector::RealType Real;
+   TNL_ASSERT( v.getSize() > 0, );
+   TNL_ASSERT( v.getSize() >= end, );
+   TNL_ASSERT( v.getSize() > begin, );
+   TNL_ASSERT( begin >= 0, );
+   TNL_ASSERT( end > begin, );
+
+   Devices::MICHider<Real> vct;
+   vct.pointer=v.getData();
+
+   #pragma offload target(mic) in(vct,begin,end)
+   {
+      Real aux( vct.pointer[ begin ] );
+      vct.pointer[ begin ] = 0.0;
+      for( Index i = begin + 1; i < end; i++ )
+      {
+         Real x = vct.pointer[ i ];
+         vct.pointer[ i ] = aux;
+         aux += x;
+      }
+   }
+}
+
+} // namespace Algorithms
+} // namespace Containers
+} // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/cuda-prefix-sum.h b/src/TNL/Containers/Algorithms/cuda-prefix-sum.h
index 2c7ec97c5dee2adea84d8c67bafce27fda4fc3aa..37215a99570676c04a9681ec0540f752e15a26f4 100644
--- a/src/TNL/Containers/Algorithms/cuda-prefix-sum.h
+++ b/src/TNL/Containers/Algorithms/cuda-prefix-sum.h
@@ -14,8 +14,11 @@ namespace TNL {
 namespace Containers {
 namespace Algorithms {
    
-enum enumPrefixSumType { exclusivePrefixSum = 0,
-                         inclusivePrefixSum };
+enum class PrefixSumType
+{
+   exclusive,
+   inclusive
+};
 
 template< typename DataType,
           typename Operation,
@@ -25,7 +28,7 @@ bool cudaPrefixSum( const Index size,
                     const DataType *deviceInput,
                     DataType* deviceOutput,
                     const Operation& operation,
-                    const enumPrefixSumType prefixSumType = inclusivePrefixSum );
+                    const PrefixSumType prefixSumType = PrefixSumType::inclusive );
 
 } // namespace Algorithms
 } // namespace Containers
diff --git a/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.h b/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.h
index d0591050d556aaca779ee2e861c6c6166b9d7346..85f8eace6944f27ce84e602b5333b153a0010c0d 100644
--- a/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.h
+++ b/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.h
@@ -11,7 +11,10 @@
 #pragma once
    
 #include <iostream>
+
+#include <TNL/Math.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Exceptions/CudaBadAlloc.h>
 #include <TNL/Containers/Algorithms/reduction-operations.h>
    
 #ifdef HAVE_CUDA
@@ -23,56 +26,56 @@ namespace Algorithms {
 template< typename DataType,
           typename Operation,
           typename Index >
-__global__ void cudaFirstPhaseBlockPrefixSum( const enumPrefixSumType prefixSumType,
-                                              Operation operation,
-                                              const Index size,
-                                              const Index elementsInBlock,
-                                              const DataType* input,
-                                              DataType* output,
-                                              DataType* auxArray )
+__global__ void
+cudaFirstPhaseBlockPrefixSum( const PrefixSumType prefixSumType,
+                              Operation operation,
+                              const Index size,
+                              const Index elementsInBlock,
+                              const DataType* input,
+                              DataType* output,
+                              DataType* auxArray )
 {
-   DataType* sharedData = TNL::Devices::getSharedMemory< DataType >();
+   DataType* sharedData = TNL::Devices::Cuda::getSharedMemory< DataType >();
    DataType* auxData = &sharedData[ elementsInBlock + elementsInBlock / Devices::Cuda::getNumberOfSharedMemoryBanks() + 2 ];
-   DataType* warpSums = &auxData[ blockDim. x ];
+   DataType* warpSums = &auxData[ blockDim.x ];
 
-   const Index lastElementIdx = size - blockIdx. x * elementsInBlock;
+   const Index lastElementIdx = size - blockIdx.x * elementsInBlock;
    Index lastElementInBlock = ( lastElementIdx < elementsInBlock ?
                                 lastElementIdx : elementsInBlock );
 
    /***
     * Load data into the shared memory.
     */
-   const Index blockOffset = blockIdx. x * elementsInBlock;
-   Index idx = threadIdx. x;
-   if( prefixSumType == exclusivePrefixSum )
+   const Index blockOffset = blockIdx.x * elementsInBlock;
+   Index idx = threadIdx.x;
+   if( prefixSumType == PrefixSumType::exclusive )
    {
       if( idx == 0 )
          sharedData[ 0 ] = operation.initialValue();
       while( idx < elementsInBlock && blockOffset + idx < size )
       {
          sharedData[ Devices::Cuda::getInterleaving( idx + 1 ) ] = input[ blockOffset + idx ];
-         idx += blockDim. x;
+         idx += blockDim.x;
       }
    }
    else
       while( idx < elementsInBlock && blockOffset + idx < size )
       {
          sharedData[ Devices::Cuda::getInterleaving( idx ) ] = input[ blockOffset + idx ];
-         idx += blockDim. x;
+         idx += blockDim.x;
       }
 
    /***
     * Perform the sequential prefix-sum.
     */
    __syncthreads();
-   const int chunkSize = elementsInBlock / blockDim. x;
-   const int chunkOffset = threadIdx. x * chunkSize;
-   const int numberOfChunks = lastElementInBlock / chunkSize +
-                            ( lastElementInBlock % chunkSize != 0 );
+   const int chunkSize = elementsInBlock / blockDim.x;
+   const int chunkOffset = threadIdx.x * chunkSize;
+   const int numberOfChunks = roundUpDivision( lastElementInBlock, chunkSize );
 
    if( chunkOffset < lastElementInBlock )
    {
-      auxData[ threadIdx. x ] =
+      auxData[ threadIdx.x ] =
          sharedData[ Devices::Cuda::getInterleaving( chunkOffset ) ];
    }
 
@@ -82,22 +85,22 @@ __global__ void cudaFirstPhaseBlockPrefixSum( const enumPrefixSumType prefixSumT
    {
       operation.commonReductionOnDevice( sharedData[ Devices::Cuda::getInterleaving( chunkOffset + chunkPointer ) ],
                                          sharedData[ Devices::Cuda::getInterleaving( chunkOffset + chunkPointer - 1 ) ] );
-      auxData[ threadIdx. x ] =
+      auxData[ threadIdx.x ] =
          sharedData[ Devices::Cuda::getInterleaving( chunkOffset + chunkPointer  ) ];
-      chunkPointer ++;
+      chunkPointer++;
    }
 
    /***
     *  Perform the parallel prefix-sum inside warps.
     */
-   const int threadInWarpIdx = threadIdx. x % Devices::Cuda::getWarpSize();
-   const int warpIdx = threadIdx. x / Devices::Cuda::getWarpSize();
+   const int threadInWarpIdx = threadIdx.x % Devices::Cuda::getWarpSize();
+   const int warpIdx = threadIdx.x / Devices::Cuda::getWarpSize();
    for( int stride = 1; stride < Devices::Cuda::getWarpSize(); stride *= 2 )
-      if( threadInWarpIdx >= stride && threadIdx. x < numberOfChunks )
-         operation.commonReductionOnDevice( auxData[ threadIdx. x ], auxData[ threadIdx. x - stride ] );
+      if( threadInWarpIdx >= stride && threadIdx.x < numberOfChunks )
+         operation.commonReductionOnDevice( auxData[ threadIdx.x ], auxData[ threadIdx.x - stride ] );
 
    if( threadInWarpIdx == Devices::Cuda::getWarpSize() - 1 )
-      warpSums[ warpIdx ] = auxData[ threadIdx. x ];
+      warpSums[ warpIdx ] = auxData[ threadIdx.x ];
    __syncthreads();
 
    /****
@@ -113,13 +116,13 @@ __global__ void cudaFirstPhaseBlockPrefixSum( const enumPrefixSumType prefixSumT
     * Shift the warp prefix-sums.
     */
    if( warpIdx > 0 )
-      operation.commonReductionOnDevice( auxData[ threadIdx. x ], warpSums[ warpIdx - 1 ] );
+      operation.commonReductionOnDevice( auxData[ threadIdx.x ], warpSums[ warpIdx - 1 ] );
 
    /***
     *  Store the result back in global memory.
     */
    __syncthreads();
-   idx = threadIdx. x;
+   idx = threadIdx.x;
    while( idx < elementsInBlock && blockOffset + idx < size )
    {
       const Index chunkIdx = idx / chunkSize;
@@ -128,49 +131,49 @@ __global__ void cudaFirstPhaseBlockPrefixSum( const enumPrefixSumType prefixSumT
          chunkShift = auxData[ chunkIdx - 1 ];
       operation.commonReductionOnDevice( sharedData[ Devices::Cuda::getInterleaving( idx ) ], chunkShift );
       output[ blockOffset + idx ] = sharedData[ Devices::Cuda::getInterleaving( idx ) ];
-      idx += blockDim. x;
+      idx += blockDim.x;
    }
    __syncthreads();
 
-   if( threadIdx. x == 0 )
+   if( threadIdx.x == 0 )
    {
-      if( prefixSumType == exclusivePrefixSum )
+      if( prefixSumType == PrefixSumType::exclusive )
       {
-         /*auxArray[ blockIdx. x ] = operation.commonReductionOnDevice( Devices::Cuda::getInterleaving( lastElementInBlock - 1 ),
+         /*auxArray[ blockIdx.x ] = operation.commonReductionOnDevice( Devices::Cuda::getInterleaving( lastElementInBlock - 1 ),
                                                                       Devices::Cuda::getInterleaving( lastElementInBlock ),
                                                                       sharedData );*/
          DataType aux = operation.initialValue();
          operation.commonReductionOnDevice( aux, sharedData[ Devices::Cuda::getInterleaving( lastElementInBlock - 1 ) ] );
          operation.commonReductionOnDevice( aux, sharedData[ Devices::Cuda::getInterleaving( lastElementInBlock ) ] );
-         auxArray[ blockIdx. x ] = aux;
+         auxArray[ blockIdx.x ] = aux;
       }
       else
-         auxArray[ blockIdx. x ] = sharedData[ Devices::Cuda::getInterleaving( lastElementInBlock - 1 ) ];
+         auxArray[ blockIdx.x ] = sharedData[ Devices::Cuda::getInterleaving( lastElementInBlock - 1 ) ];
    }
-
 }
 
 template< typename DataType,
           typename Operation,
           typename Index >
-__global__ void cudaSecondPhaseBlockPrefixSum( Operation operation,
-                                               const Index size,
-                                               const Index elementsInBlock,
-                                               const Index gridShift,
-                                               const DataType* auxArray,
-                                               DataType* data )
+__global__ void
+cudaSecondPhaseBlockPrefixSum( Operation operation,
+                               const Index size,
+                               const Index elementsInBlock,
+                               const Index gridShift,
+                               const DataType* auxArray,
+                               DataType* data )
 {
-   if( blockIdx. x > 0 )
+   if( blockIdx.x > 0 )
    {
       DataType shift( gridShift );
-      operation.commonReductionOnDevice( shift, auxArray[ blockIdx. x - 1 ] );
+      operation.commonReductionOnDevice( shift, auxArray[ blockIdx.x - 1 ] );
 
-      const Index readOffset = blockIdx. x * elementsInBlock;
-      Index readIdx = threadIdx. x;
+      const Index readOffset = blockIdx.x * elementsInBlock;
+      Index readIdx = threadIdx.x;
       while( readIdx < elementsInBlock && readOffset + readIdx < size )
       {
          operation.commonReductionOnDevice( data[ readIdx + readOffset ], shift );
-         readIdx += blockDim. x;
+         readIdx += blockDim.x;
       }
    }
 }
@@ -179,89 +182,69 @@ __global__ void cudaSecondPhaseBlockPrefixSum( Operation operation,
 template< typename DataType,
           typename Operation,
           typename Index >
-bool cudaRecursivePrefixSum( const enumPrefixSumType prefixSumType,
-                             Operation& operation,
-                             const Index size,
-                             const Index blockSize,
-                             const Index elementsInBlock,
-                             const Index gridShift,
-                             const DataType* input,
-                             DataType *output )
+void
+cudaRecursivePrefixSum( const PrefixSumType prefixSumType,
+                        Operation& operation,
+                        const Index size,
+                        const Index blockSize,
+                        const Index elementsInBlock,
+                        const Index gridShift,
+                        const DataType* input,
+                        DataType *output )
 {
-   const Index numberOfBlocks = ceil( ( double ) size / ( double ) elementsInBlock );
+   const Index numberOfBlocks = roundUpDivision( size, elementsInBlock );
    const Index auxArraySize = numberOfBlocks * sizeof( DataType );
-   DataType *auxArray1, *auxArray2;
 
-   if( cudaMalloc( ( void** ) &auxArray1, auxArraySize ) != cudaSuccess ||
-       cudaMalloc( ( void** ) &auxArray2, auxArraySize ) != cudaSuccess  )
-   {
-      {
-         std::cerr << "Not enough memory on device to allocate auxilliary arrays." << std::endl;
-         return false;
-      }
-   }
+   Array< DataType, Devices::Cuda > auxArray1, auxArray2;
+   auxArray1.setSize( auxArraySize );
+   auxArray2.setSize( auxArraySize );
 
    /****
     * Setup block and grid size.
     */
    dim3 cudaBlockSize( 0 ), cudaGridSize( 0 );
-   cudaBlockSize. x = blockSize;
-   cudaGridSize. x = size / elementsInBlock +
-                     ( size % elementsInBlock != 0 );
+   cudaBlockSize.x = blockSize;
+   cudaGridSize.x = roundUpDivision( size, elementsInBlock );
 
    /****
     * Run the kernel.
     */
-   size_t sharedDataSize = elementsInBlock +
-                           elementsInBlock / Devices::Cuda::getNumberOfSharedMemoryBanks() + 2;
-   size_t sharedMemory = ( sharedDataSize + blockSize + Devices::Cuda::getWarpSize()  ) * sizeof( DataType );
-   cudaFirstPhaseBlockPrefixSum< DataType, Operation, Index >
-                                <<< cudaGridSize, cudaBlockSize, sharedMemory >>>
-                                (  prefixSumType,
-                                   operation,
-                                   size,
-                                   elementsInBlock,
-                                   input,
-                                   output,
-                                   auxArray1 );
-   if( ! checkCudaDevice )
-   {
-      std::cerr << "The CUDA kernel 'cudaFirstPhaseBlockPrefixSum' ended with error." << std::endl;
-      cudaFree( auxArray1 );
-      cudaFree( auxArray2 );
-      return false;
-   }
+   const std::size_t sharedDataSize = elementsInBlock +
+                                      elementsInBlock / Devices::Cuda::getNumberOfSharedMemoryBanks() + 2;
+   const std::size_t sharedMemory = ( sharedDataSize + blockSize + Devices::Cuda::getWarpSize()  ) * sizeof( DataType );
+   cudaFirstPhaseBlockPrefixSum<<< cudaGridSize, cudaBlockSize, sharedMemory >>>
+      ( prefixSumType,
+        operation,
+        size,
+        elementsInBlock,
+        input,
+        output,
+        auxArray1.getData() );
+   TNL_CHECK_CUDA_DEVICE;
 
    /***
     * In auxArray1 there is now a sum of numbers in each block.
     * We must compute prefix-sum of auxArray1 and then shift
     * each block.
     */
-   if( numberOfBlocks > 1 &&
-       ! cudaRecursivePrefixSum< DataType, Operation, Index >
-                               ( inclusivePrefixSum,
-                                 operation,
-                                 numberOfBlocks,
-                                 blockSize,
-                                 elementsInBlock,
-                                 0,
-                                 auxArray1,
-                                 auxArray2 ) )
-      return false;
-   cudaSecondPhaseBlockPrefixSum< DataType, Operation, Index >
-                                <<< cudaGridSize, cudaBlockSize >>>
-                                 ( operation, size, elementsInBlock, gridShift, auxArray2, output );
-
-   if( ! checkCudaDevice )
-   {
-      std::cerr << "The CUDA kernel 'cudaSecondPhaseBlockPrefixSum' ended with error." << std::endl;
-      cudaFree( auxArray1 );
-      cudaFree( auxArray2 );
-      return false;
-   }
-   cudaFree( auxArray1 );
-   cudaFree( auxArray2 );
-   return true;
+   if( numberOfBlocks > 1 )
+       cudaRecursivePrefixSum( PrefixSumType::inclusive,
+                               operation,
+                               numberOfBlocks,
+                               blockSize,
+                               elementsInBlock,
+                               (Index) 0,
+                               auxArray1.getData(),
+                               auxArray2.getData() );
+
+   cudaSecondPhaseBlockPrefixSum<<< cudaGridSize, cudaBlockSize >>>
+      ( operation,
+        size,
+        elementsInBlock,
+        gridShift,
+        auxArray2.getData(),
+        output );
+   TNL_CHECK_CUDA_DEVICE;
 }
 
 
@@ -269,85 +252,74 @@ bool cudaRecursivePrefixSum( const enumPrefixSumType prefixSumType,
 template< typename DataType,
           typename Operation,
           typename Index >
-bool cudaGridPrefixSum( enumPrefixSumType prefixSumType,
-                        Operation& operation,
-                        const Index size,
-                        const Index blockSize,
-                        const Index elementsInBlock,
-                        const DataType *deviceInput,
-                        DataType *deviceOutput,
-                        Index& gridShift )
+void
+cudaGridPrefixSum( PrefixSumType prefixSumType,
+                   Operation& operation,
+                   const Index size,
+                   const Index blockSize,
+                   const Index elementsInBlock,
+                   const DataType *deviceInput,
+                   DataType *deviceOutput,
+                   Index& gridShift )
 {
-
-   if( ! cudaRecursivePrefixSum< DataType, Operation, Index >
-                               ( prefixSumType,
-                                 operation,
-                                 size,
-                                 blockSize,
-                                 elementsInBlock,
-                                 gridShift,
-                                 deviceInput,
-                                 deviceOutput ) )
-      return false;
-   if( cudaMemcpy( &gridShift,
-                   &deviceOutput[ size - 1 ],
-                   sizeof( DataType ),
-                   cudaMemcpyDeviceToHost ) != cudaSuccess )
-   {
-      std::cerr << "I am not able to copy data from device to host." << std::endl;
-      return false;
-   }
-   return true;
+   cudaRecursivePrefixSum( prefixSumType,
+                           operation,
+                           size,
+                           blockSize,
+                           elementsInBlock,
+                           gridShift,
+                           deviceInput,
+                           deviceOutput );
+
+   cudaMemcpy( &gridShift,
+               &deviceOutput[ size - 1 ],
+               sizeof( DataType ),
+               cudaMemcpyDeviceToHost );
+   TNL_CHECK_CUDA_DEVICE;
 }
 
 template< typename DataType,
           typename Operation,
           typename Index >
-bool cudaPrefixSum( const Index size,
-                    const Index blockSize,
-                    const DataType *deviceInput,
-                    DataType* deviceOutput,
-                    Operation& operation,
-                    const enumPrefixSumType prefixSumType )
+void
+cudaPrefixSum( const Index size,
+               const Index blockSize,
+               const DataType *deviceInput,
+               DataType* deviceOutput,
+               Operation& operation,
+               const PrefixSumType prefixSumType )
 {
    /****
     * Compute the number of grids
     */
    const Index elementsInBlock = 8 * blockSize;
-   const Index gridSize = size / elementsInBlock + ( size % elementsInBlock != 0 );
-   const Index maxGridSize = 65536;
-   const Index gridsNumber = gridSize / maxGridSize + ( gridSize % maxGridSize != 0 );
+   const Index numberOfBlocks = roundUpDivision( size, elementsInBlock );
+   const auto maxGridSize = Devices::Cuda::getMaxGridSize();
+   const Index numberOfGrids = Devices::Cuda::getNumberOfGrids( numberOfBlocks, maxGridSize );
 
    /****
     * Loop over all grids.
     */
-   Index gridShift( 0 );
-   for( Index gridIdx = 0; gridIdx < gridsNumber; gridIdx ++ )
+   Index gridShift = 0;
+   for( Index gridIdx = 0; gridIdx < numberOfGrids; gridIdx++ )
    {
       /****
        * Compute current grid size and size of data to be scanned
        */
-      Index gridSize = ( size - gridIdx * maxGridSize * elementsInBlock ) /
-                     elementsInBlock;
       Index currentSize = size - gridIdx * maxGridSize * elementsInBlock;
-      if( gridSize > maxGridSize )
-      {
-         gridSize = maxGridSize;
+      if( currentSize / elementsInBlock > maxGridSize )
          currentSize = maxGridSize * elementsInBlock;
-      }
-      Index gridOffset = gridIdx * maxGridSize * elementsInBlock;
-      if( ! cudaGridPrefixSum< DataType, Operation, Index >
-                             ( prefixSumType,
-                               operation,
-                               currentSize,
-                               blockSize,
-                               elementsInBlock,
-                               &deviceInput[ gridOffset ],
-                               &deviceOutput[ gridOffset ],
-                               gridShift ) )
-         return false;
+      const Index gridOffset = gridIdx * maxGridSize * elementsInBlock;
+
+      cudaGridPrefixSum( prefixSumType,
+                         operation,
+                         currentSize,
+                         blockSize,
+                         elementsInBlock,
+                         &deviceInput[ gridOffset ],
+                         &deviceOutput[ gridOffset ],
+                         gridShift );
    }
-   return true;
 }
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
@@ -356,7 +328,7 @@ extern template bool cudaPrefixSum( const int size,
                                     const int *deviceInput,
                                     int* deviceOutput,
                                     tnlParallelReductionSum< int, int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 
 extern template bool cudaPrefixSum( const int size,
@@ -364,14 +336,14 @@ extern template bool cudaPrefixSum( const int size,
                                     const float *deviceInput,
                                     float* deviceOutput,
                                     tnlParallelReductionSum< float, int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 extern template bool cudaPrefixSum( const int size,
                                     const int blockSize,
                                     const double *deviceInput,
                                     double* deviceOutput,
                                     tnlParallelReductionSum< double, int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 #ifdef INSTANTIATE_LONG_DOUBLE
 extern template bool cudaPrefixSum( const int size,
@@ -379,7 +351,7 @@ extern template bool cudaPrefixSum( const int size,
                                     const long double *deviceInput,
                                     long double* deviceOutput,
                                     tnlParallelReductionSum< long double, int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 #endif
 
 #ifdef INSTANTIATE_LONG_INT
@@ -388,7 +360,7 @@ extern template bool cudaPrefixSum( const long int size,
                                     const int *deviceInput,
                                     int* deviceOutput,
                                     tnlParallelReductionSum< int, long int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 
 extern template bool cudaPrefixSum( const long int size,
@@ -396,14 +368,14 @@ extern template bool cudaPrefixSum( const long int size,
                                     const float *deviceInput,
                                     float* deviceOutput,
                                     tnlParallelReductionSum< float, long int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 extern template bool cudaPrefixSum( const long int size,
                                     const long int blockSize,
                                     const double *deviceInput,
                                     double* deviceOutput,
                                     tnlParallelReductionSum< double, long int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 
 #ifdef INSTANTIATE_LONG_DOUBLE
 extern template bool cudaPrefixSum( const long int size,
@@ -411,7 +383,7 @@ extern template bool cudaPrefixSum( const long int size,
                                     const long double *deviceInput,
                                     long double* deviceOutput,
                                     tnlParallelReductionSum< long double, long int >& operation,
-                                    const enumPrefixSumType prefixSumType );
+                                    const PrefixSumType prefixSumType );
 #endif
 #endif
 
diff --git a/src/TNL/Containers/Algorithms/reduction-operations.h b/src/TNL/Containers/Algorithms/reduction-operations.h
index deec09a3c55a19f1bfde4aa03514be371b4c36d8..8d5499448457651789e122261c62fe03fa959cc8 100644
--- a/src/TNL/Containers/Algorithms/reduction-operations.h
+++ b/src/TNL/Containers/Algorithms/reduction-operations.h
@@ -76,7 +76,7 @@ class tnlParallelReductionMin
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return min( current, data1[ idx ] );
+      return TNL::min( current, data1[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return MaxValue< ResultType>(); };
@@ -117,7 +117,7 @@ class tnlParallelReductionMax
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return max( current, data1[ idx ] );
+      return TNL::max( current, data1[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return MinValue< ResultType>(); };
@@ -241,7 +241,7 @@ class tnlParallelReductionAbsSum : public tnlParallelReductionSum< Real, Index >
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return current + ::abs( data1[ idx ] );
+      return current + TNL::abs( data1[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -270,7 +270,7 @@ class tnlParallelReductionAbsMin : public tnlParallelReductionMin< Real, Index >
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return min( current, abs( data1[ idx ] ) );
+      return TNL::min( current, TNL::abs( data1[ idx ] ) );
    };
 
    __cuda_callable__ ResultType initialValue() { return MaxValue< ResultType>(); };
@@ -299,7 +299,7 @@ class tnlParallelReductionAbsMax : public tnlParallelReductionMax< Real, Index >
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return std::max( current, ::abs( data1[ idx ] ) );
+      return std::max( current, TNL::abs( data1[ idx ] ) );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -365,7 +365,7 @@ class tnlParallelReductionLpNorm : public tnlParallelReductionSum< Real, Index >
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return current + ::pow( ::abs( data1[ idx ] ), p );
+      return current + TNL::pow( TNL::abs( data1[ idx ] ), p );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -514,7 +514,7 @@ class tnlParallelReductionDiffMin : public tnlParallelReductionMin< Real, Index
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return min( current, data1[ idx ] - data2[ idx ] );
+      return TNL::min( current, data1[ idx ] - data2[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return MaxValue< ResultType>(); };
@@ -543,7 +543,7 @@ class tnlParallelReductionDiffMax : public tnlParallelReductionMax< Real, Index
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return max( current, data1[ idx ] - data2[ idx ] );
+      return TNL::max( current, data1[ idx ] - data2[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -572,7 +572,7 @@ class tnlParallelReductionDiffAbsSum : public tnlParallelReductionMax< Real, Ind
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return current + abs( data1[ idx ] - data2[ idx ] );
+      return current + TNL::abs( data1[ idx ] - data2[ idx ] );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -601,7 +601,7 @@ class tnlParallelReductionDiffAbsMin : public tnlParallelReductionMin< Real, Ind
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return min( current, abs( data1[ idx ] - data2[ idx ] ) );
+      return TNL::min( current, TNL::abs( data1[ idx ] - data2[ idx ] ) );
    };
 
    __cuda_callable__ ResultType initialValue() { return MaxValue< ResultType>(); };
@@ -630,7 +630,7 @@ class tnlParallelReductionDiffAbsMax : public tnlParallelReductionMax< Real, Ind
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return max( current, abs( data1[ idx ] - data2[ idx ] ) );
+      return TNL::max( current, TNL::abs( data1[ idx ] - data2[ idx ] ) );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
@@ -699,7 +699,7 @@ class tnlParallelReductionDiffLpNorm : public tnlParallelReductionSum< Real, Ind
                             const RealType* data1,
                             const RealType* data2 )
    {
-      return current + ::pow( abs( data1[ idx ] - data2[ idx ] ), p );
+      return current + TNL::pow( TNL::abs( data1[ idx ] - data2[ idx ] ), p );
    };
 
    __cuda_callable__ ResultType initialValue() { return ( ResultType ) 0; };
diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h
index 8eb769622002c12ac6d5d55d68cc22d4ffeea175..89e72cb8b4f87731f2b31065901bde59c4954510 100644
--- a/src/TNL/Containers/Array.h
+++ b/src/TNL/Containers/Array.h
@@ -8,25 +8,16 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#pragma once 
+#pragma once
 
 #include <TNL/Object.h>
-#include <TNL/Containers/SharedArray.h>
+#include <TNL/File.h>
+#include <TNL/Devices/Host.h>
 
-// Forward declarations
 namespace TNL {
-class File;
-
-namespace Devices {
-   class Host;
-}
-
-
 namespace Containers {
 
-
-template< typename Element, typename Device, typename Index >
-class SharedArray;
+template< int, typename > class StaticArray;
 
 /****
  * Array handles memory allocation and sharing of the same data between more Arrays.
@@ -44,18 +35,17 @@ class Array : public virtual Object
       typedef Index IndexType;
       typedef Containers::Array< Element, Devices::Host, Index > HostType;
       typedef Containers::Array< Element, Devices::Cuda, Index > CudaType;
-      typedef Containers::Array< Element, Device, Index > ThisType;
- 
+
       Array();
- 
+
       Array( const IndexType& size );
- 
+
       Array( Element* data,
-                const IndexType& size );
+             const IndexType& size );
 
-      Array( Array< Element, Device, Index >& array,
-                const IndexType& begin = 0,
-                const IndexType& size = 0 );
+      Array( Array& array,
+             const IndexType& begin = 0,
+             const IndexType& size = 0 );
 
       static String getType();
 
@@ -70,28 +60,28 @@ class Array : public virtual Object
        * these data are released. If the current data are not shared and the current
        * size is the same as the new one, nothing happens.
        */
-      bool setSize( Index size );
+      void setSize( Index size );
 
-      template< typename Array >
-      bool setLike( const Array& array );
+      __cuda_callable__ Index getSize() const;
+
+      template< typename ArrayT >
+      void setLike( const ArrayT& array );
 
       void bind( Element* _data,
                  const Index _size );
 
-      template< typename Array >      
-      void bind( const Array& array,
+      template< typename ArrayT >
+      void bind( const ArrayT& array,
                  const IndexType& begin = 0,
                  const IndexType& size = 0 );
 
       template< int Size >
       void bind( StaticArray< Size, Element >& array );
 
-      void swap( Array< Element, Device, Index >& array );
+      void swap( Array& array );
 
       void reset();
 
-      __cuda_callable__ Index getSize() const;
-
       void setElement( const Index& i, const Element& x );
 
       Element getElement( const Index& i ) const;
@@ -100,10 +90,10 @@ class Array : public virtual Object
 
       __cuda_callable__ inline const Element& operator[] ( const Index& i ) const;
 
-      Array< Element, Device, Index >& operator = ( const Array< Element, Device, Index >& array );
+      Array& operator = ( const Array& array );
 
       template< typename ArrayT >
-      Array< Element, Device, Index >& operator = ( const ArrayT& array );
+      Array& operator = ( const ArrayT& array );
 
       template< typename ArrayT >
       bool operator == ( const ArrayT& array ) const;
@@ -127,20 +117,15 @@ class Array : public virtual Object
        * Every time one touches this grid touches * size * sizeof( Real ) bytes are added
        * to transfered bytes in tnlStatistics.
        */
-   #ifdef HAVE_NOT_CXX11
-      template< typename IndexType2 >
-      void touch( IndexType2 touches = 1 ) const;
-   #else
       template< typename IndexType2 = Index >
       void touch( IndexType2 touches = 1 ) const;
-   #endif
 
       //! Method for saving the object to a file as a binary data.
       bool save( File& file ) const;
 
       //! Method for loading the object from a file as a binary data.
       bool load( File& file );
- 
+
       //! This method loads data without reallocation.
       /****
        * This is useful for loading data into shared arrays.
@@ -149,17 +134,17 @@ class Array : public virtual Object
        * the size of array being loaded.
        */
       bool boundLoad( File& file );
- 
-      bool boundLoad( const String& fileName );
- 
-      using Object::load;
 
       using Object::save;
 
+      using Object::load;
+
+      using Object::boundLoad;
+
       ~Array();
 
    protected:
- 
+
       void releaseData() const;
 
       //!Number of elements in array
@@ -192,4 +177,3 @@ std::ostream& operator << ( std::ostream& str, const Array< Element, Device, Ind
 } // namespace TNL
 
 #include <TNL/Containers/Array_impl.h>
-
diff --git a/src/TNL/Containers/Array_impl.cpp b/src/TNL/Containers/Array_impl.cpp
index 966b0e5f35292a6a0a000b5b030108d67769b4be..c951e0526badefc0806979821e2b0decfbdc2cdf 100644
--- a/src/TNL/Containers/Array_impl.cpp
+++ b/src/TNL/Containers/Array_impl.cpp
@@ -8,13 +8,13 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
+
 #include <TNL/Containers/Array.h>
 
 namespace TNL {
 namespace Containers {
 
-#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
-
 #ifdef INSTANTIATE_FLOAT
 template class Array< float, Devices::Host, int >;
 #endif
@@ -55,7 +55,7 @@ template class Array< long double, Devices::Cuda, long int >;
 
 #endif
 
-#endif
-
 } // namespace Containers
-} // namespace TNL
\ No newline at end of file
+} // namespace TNL
+
+#endif // #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Containers/Array_impl.cu b/src/TNL/Containers/Array_impl.cu
index b14e5c30d96f7987b87595afff37d0da2ae00ac7..5c43ec36e69ccb02b2b9950d85e27f9271192b3d 100644
--- a/src/TNL/Containers/Array_impl.cu
+++ b/src/TNL/Containers/Array_impl.cu
@@ -8,13 +8,13 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
+
 #include <TNL/Containers/Array.h>
 
 namespace TNL {
 namespace Containers {
 
-#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
-
 #ifdef HAVE_CUDA
 #ifdef INSTANTIATE_FLOAT
 template class Array< float, Devices::Cuda, int >;
@@ -37,7 +37,7 @@ template class Array< long double, Devices::Cuda, long int >;
 
 #endif
 
-#endif
-
 } // namespace Containers
 } // namespace TNL
+
+#endif // #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h
index df751fcd420a212883ffd3944c72a77eb89f4398..52504e47a31f057adf878c86e32891a1210daa7c 100644
--- a/src/TNL/Containers/Array_impl.h
+++ b/src/TNL/Containers/Array_impl.h
@@ -15,16 +15,16 @@
 #include <TNL/File.h>
 #include <TNL/Math.h>
 #include <TNL/param-types.h>
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Containers/ArrayIO.h>
 #include <TNL/Containers/Array.h>
 
 namespace TNL {
-namespace Containers {   
+namespace Containers {
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Array< Element, Device, Index >::
 Array()
 : size( 0 ),
@@ -32,11 +32,11 @@ Array()
   allocationPointer( 0 ),
   referenceCounter( 0 )
 {
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Array< Element, Device, Index >::
 Array( const IndexType& size )
 : size( 0 ),
@@ -48,11 +48,11 @@ Array( const IndexType& size )
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Array< Element, Device, Index >::
 Array( Element* data,
-          const IndexType& size )
+       const IndexType& size )
 : size( size ),
   data( data ),
   allocationPointer( 0 ),
@@ -61,21 +61,21 @@ Array( Element* data,
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Array< Element, Device, Index >::
 Array( Array< Element, Device, Index >& array,
-          const IndexType& begin,
-          const IndexType& size )
+       const IndexType& begin,
+       const IndexType& size )
 : size( size ),
   data( &array.getData()[ begin ] ),
   allocationPointer( array.allocationPointer ),
   referenceCounter( 0 )
 {
-   Assert( begin < array.getSize(),
-              std::cerr << " begin = " << begin << " array.getSize() = " << array.getSize() );
-   Assert( begin + size  < array.getSize(),
-              std::cerr << " begin = " << begin << " size = " << size <<  " array.getSize() = " << array.getSize() );
+   TNL_ASSERT_TRUE( array.getData(), "Empty arrays cannot be bound." );
+   TNL_ASSERT_LT( begin, array.getSize(), "Begin of array is out of bounds." );
+   TNL_ASSERT_LE( begin + size, array.getSize(), "End of array is out of bounds." );
+
    if( ! this->size )
       this->size = array.getSize() - begin;
    if( array.allocationPointer )
@@ -103,41 +103,41 @@ getType()
           TNL::getType< Element >() + ", " +
           Device::getDeviceType() + ", " +
           TNL::getType< Index >() + " >";
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 String
 Array< Element, Device, Index >::
 getTypeVirtual() const
 {
    return this->getType();
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 String
 Array< Element, Device, Index >::
 getSerializationType()
 {
    return HostType::getType();
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 String
 Array< Element, Device, Index >::
 getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 void
 Array< Element, Device, Index >::
 releaseData() const
@@ -146,14 +146,14 @@ releaseData() const
    {
       if( --*this->referenceCounter == 0 )
       {
-         ArrayOperations< Device >::freeMemory( this->allocationPointer );
+         Algorithms::ArrayOperations< Device >::freeMemory( this->allocationPointer );
          delete this->referenceCounter;
          //std::cerr << "Deallocating reference counter " << this->referenceCounter << std::endl;
       }
    }
    else
       if( allocationPointer )
-         ArrayOperations< Device >::freeMemory( this->allocationPointer );
+         Algorithms::ArrayOperations< Device >::freeMemory( this->allocationPointer );
    this->allocationPointer = 0;
    this->data = 0;
    this->size = 0;
@@ -163,58 +163,66 @@ releaseData() const
 template< typename Element,
           typename Device,
           typename Index >
-bool
+void
 Array< Element, Device, Index >::
 setSize( const Index size )
 {
-   Assert( size >= 0,
-              std::cerr << "You try to set size of Array to negative value."
-                        << "New size: " << size << std::endl );
-   if( this->size == size && allocationPointer && ! referenceCounter ) return true;
+   TNL_ASSERT_GE( size, 0, "Array size must be non-negative." );
+
+   if( this->size == size && allocationPointer && ! referenceCounter )
+      return;
    this->releaseData();
-   ArrayOperations< Device >::allocateMemory( this->allocationPointer, size );
-   this->data = this->allocationPointer;
-   this->size = size;
-   if( ! this->allocationPointer )
-   {
-      std::cerr << "I am not able to allocate new array with size "
-                << ( double ) this->size * sizeof( ElementType ) / 1.0e9 << " GB." << std::endl;
-      this->size = 0;
-      return false;
+
+   // Allocating zero bytes is useless. Moreover, the allocators don't behave the same way:
+   // "operator new" returns some non-zero address, the latter returns a null pointer.
+   if( size > 0 ) {
+      Algorithms::ArrayOperations< Device >::allocateMemory( this->allocationPointer, size );
+      this->data = this->allocationPointer;
+      this->size = size;
+      TNL_ASSERT_TRUE( this->allocationPointer,
+                       "This should never happen - allocator did not throw on an error." );
    }
-   return true;
-};
+}
+
+template< typename Element,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index
+Array< Element, Device, Index >::
+getSize() const
+{
+   return this -> size;
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
    template< typename ArrayT >
-bool
+void
 Array< Element, Device, Index >::
 setLike( const ArrayT& array )
 {
-   Assert( array. getSize() >= 0,
-              std::cerr << "You try to set size of Array to negative value."
-                        << "Array size: " << array. getSize() << std::endl );
-   return setSize( array.getSize() );
-};
+   setSize( array.getSize() );
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 void
 Array< Element, Device, Index >::
 bind( Element* data,
       const Index size )
 {
+   TNL_ASSERT_TRUE( data, "Null pointer cannot be bound." );
    this->releaseData();
    this->data = data;
    this->size = size;
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
    template< typename ArrayT >
 void
 Array< Element, Device, Index >::
@@ -222,12 +230,14 @@ bind( const ArrayT& array,
       const IndexType& begin,
       const IndexType& size )
 {
-   Assert( ( std::is_same< Device, typename ArrayT::DeviceType>::value ), );
-   Assert( begin <= array.getSize(),
-              std::cerr << " begin = " << begin << " array.getSize() = " << array.getSize() );
-   Assert( begin + size  <= array.getSize(),
-              std::cerr << " begin = " << begin << " size = " << size <<  " array.getSize() = " << array.getSize() );
- 
+   // all template parameters of Array must match, otherwise binding does not make sense
+   static_assert( std::is_same< Element, typename ArrayT::ElementType >::value, "ElementType of both arrays must be the same." );
+   static_assert( std::is_same< Device, typename ArrayT::DeviceType >::value, "DeviceType of both arrays must be the same." );
+   static_assert( std::is_same< Index, typename ArrayT::IndexType >::value, "IndexType of both arrays must be the same." );
+   TNL_ASSERT_TRUE( array.getData(), "Empty array cannot be bound." );
+   TNL_ASSERT_LT( begin, array.getSize(), "Begin of array is out of bounds." );
+   TNL_ASSERT_LE( begin + size, array.getSize(), "End of array is out of bounds." );
+
    this->releaseData();
    if( size )
       this->size = size;
@@ -244,16 +254,15 @@ bind( const ArrayT& array,
       }
       else
       {
-         this->referenceCounter = array.referenceCounter = new int;
-         *this->referenceCounter = 2;
+         this->referenceCounter = array.referenceCounter = new int( 2 );
          //std::cerr << "Allocating reference counter " << this->referenceCounter << std::endl;
       }
    }
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
    template< int Size >
 void
 Array< Element, Device, Index >::
@@ -276,7 +285,7 @@ swap( Array< Element, Device, Index >& array )
    TNL::swap( this->data, array.data );
    TNL::swap( this->allocationPointer, array.allocationPointer );
    TNL::swap( this->referenceCounter, array.referenceCounter );
-};
+}
 
 template< typename Element,
           typename Device,
@@ -286,46 +295,31 @@ Array< Element, Device, Index >::
 reset()
 {
    this->releaseData();
-};
+}
 
 template< typename Element,
           typename Device,
           typename Index >
-__cuda_callable__
-Index
-Array< Element, Device, Index >::
-getSize() const
-{
-   return this->size;
-}
-
-template< typename Element,
-           typename Device,
-           typename Index >
 void
 Array< Element, Device, Index >::
 setElement( const Index& i, const Element& x )
 {
-   Assert( 0 <= i && i < this->getSize(),
-              std::cerr << "Wrong index for setElement method in Array "
-                        << " index is " << i
-                        << " and array size is " << this->getSize() );
-   return ArrayOperations< Device > :: setMemoryElement( &( this->data[ i ] ), x );
-};
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
+   return Algorithms::ArrayOperations< Device >::setMemoryElement( &( this->data[ i ] ), x );
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Element
 Array< Element, Device, Index >::
 getElement( const Index& i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
-              std::cerr << "Wrong index for getElement method in Array "
-                        << " index is " << i
-                        << " and array size is " << this->getSize() );
-   return ArrayOperations< Device >::getMemoryElement( & ( this->data[ i ] ) );
-};
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
+   return Algorithms::ArrayOperations< Device >::getMemoryElement( & ( this->data[ i ] ) );
+}
 
 template< typename Element,
           typename Device,
@@ -335,68 +329,66 @@ inline Element&
 Array< Element, Device, Index >::
 operator[] ( const Index& i )
 {
-   Assert( 0 <= i && i < this->getSize(),
-              std::cerr << "Wrong index for operator[] in Array "
-                        << " index is " << i
-                        << " and array size is " << this->getSize() );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
    return this->data[ i ];
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 __cuda_callable__
 inline const Element&
 Array< Element, Device, Index >::
 operator[] ( const Index& i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
-              std::cerr << "Wrong index for operator[] in Array "
-                        << " index is " << i
-                        << " and array size is " << this->getSize() );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
    return this->data[ i ];
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Array< Element, Device, Index >&
 Array< Element, Device, Index >::
 operator = ( const Array< Element, Device, Index >& array )
 {
-   Assert( array. getSize() == this->getSize(),
-              std::cerr << "Source size: " << array. getSize() << std::endl
-                        << "Target size: " << this->getSize() << std::endl );
-   ArrayOperations< Device > ::
-   template copyMemory< Element,
-                        Element,
-                        Index >
-                       ( this->getData(),
-                         array. getData(),
-                         array. getSize() );
+   //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." );
+   if( this->getSize() != array.getSize() )
+      this->setLike( array );
+   if( this->getSize() > 0 )
+      Algorithms::ArrayOperations< Device >::
+         template copyMemory< Element,
+                              Element,
+                              Index >
+                             ( this->getData(),
+                               array.getData(),
+                               array.getSize() );
    return ( *this );
-};
+}
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
    template< typename ArrayT >
 Array< Element, Device, Index >&
 Array< Element, Device, Index >::
 operator = ( const ArrayT& array )
 {
-   Assert( array. getSize() == this->getSize(),
-              std::cerr << "Source size: " << array. getSize() << std::endl
-                        << "Target size: " << this->getSize() << std::endl );
-   ArrayOperations< Device, typename ArrayT::DeviceType > ::
-    template copyMemory< Element,
-                         typename ArrayT::ElementType,
-                         typename ArrayT::IndexType >
-                       ( this->getData(),
-                         array. getData(),
-                         array. getSize() );
+   //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." );
+   if( this->getSize() != array.getSize() )
+      this->setLike( array );   
+   if( this->getSize() > 0 )
+      Algorithms::ArrayOperations< Device, typename ArrayT::DeviceType >::
+         template copyMemory< Element,
+                              typename ArrayT::ElementType,
+                              typename ArrayT::IndexType >
+                            ( this->getData(),
+                              array.getData(),
+                              array.getSize() );
    return ( *this );
-};
+}
 
 template< typename Element,
           typename Device,
@@ -406,22 +398,24 @@ bool
 Array< Element, Device, Index >::
 operator == ( const ArrayT& array ) const
 {
-   if( array. getSize() != this->getSize() )
+   if( array.getSize() != this->getSize() )
       return false;
-   return ArrayOperations< Device, typename ArrayT::DeviceType > ::
-    template compareMemory< typename ArrayT::ElementType,
-                            Element,
-                            typename ArrayT::IndexType >
-                          ( this->getData(),
-                            array.getData(),
-                            array.getSize() );
+   if( this->getSize() == 0 )
+      return true;
+   return Algorithms::ArrayOperations< Device, typename ArrayT::DeviceType >::
+      template compareMemory< typename ArrayT::ElementType,
+                              Element,
+                              typename ArrayT::IndexType >
+                            ( this->getData(),
+                              array.getData(),
+                              array.getSize() );
 }
 
 template< typename Element,
           typename Device,
           typename Index >
    template< typename ArrayT >
-bool Array< Element, Device, Index > :: operator != ( const ArrayT& array ) const
+bool Array< Element, Device, Index >::operator != ( const ArrayT& array ) const
 {
    return ! ( ( *this ) == array );
 }
@@ -430,70 +424,65 @@ bool Array< Element, Device, Index > :: operator != ( const ArrayT& array ) cons
 template< typename Element,
           typename Device,
           typename Index >
-void Array< Element, Device, Index > :: setValue( const Element& e )
+void Array< Element, Device, Index >::setValue( const Element& e )
 {
-   Assert( this->getData(),);
-   ArrayOperations< Device > :: setMemory( this->getData(), e, this->getSize() );
+   TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array." );
+   Algorithms::ArrayOperations< Device >::setMemory( this->getData(), e, this->getSize() );
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 __cuda_callable__
-const Element* Array< Element, Device, Index > :: getData() const
+const Element* Array< Element, Device, Index >::getData() const
 {
-   return this->data;
+   return this -> data;
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 __cuda_callable__
-Element* Array< Element, Device, Index > :: getData()
+Element* Array< Element, Device, Index >::getData()
 {
-   return this->data;
+   return this -> data;
 }
 
 template< typename Element,
-           typename Device,
-           typename Index >
-Array< Element, Device, Index > :: operator bool() const
+          typename Device,
+          typename Index >
+Array< Element, Device, Index >::operator bool() const
 {
    return data != 0;
-};
+}
 
 
 template< typename Element,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
    template< typename IndexType2 >
-void Array< Element, Device, Index > :: touch( IndexType2 touches ) const
+void Array< Element, Device, Index >::touch( IndexType2 touches ) const
 {
    //TODO: implement
-};
+}
 
 template< typename Element,
           typename Device,
           typename Index >
-bool Array< Element, Device, Index > :: save( File& file ) const
+bool Array< Element, Device, Index >::save( File& file ) const
 {
-   if( ! Object :: save( file ) )
-      return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< const Index, Devices::Host >( &this->size ) )
+   if( ! Object::save( file ) )
       return false;
-#else
-   if( ! file. write( &this->size ) )
+   if( ! file.write( &this->size ) )
       return false;
-#endif
    if( this->size != 0 && ! ArrayIO< Element, Device, Index >::save( file, this->data, this->size ) )
    {
       std::cerr << "I was not able to save " << this->getType()
-                << " with size " << this->getSize() << std::endl;
+           << " with size " << this -> getSize() << std::endl;
       return false;
    }
    return true;
-};
+}
 
 template< typename Element,
           typename Device,
@@ -502,16 +491,14 @@ bool
 Array< Element, Device, Index >::
 load( File& file )
 {
-   if( ! Object :: load( file ) )
+   if( ! Object::load( file ) )
       return false;
    Index _size;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< Index, Devices::Host >( &_size ) )
-      return false;
-#else
-   if( ! file. read( &_size ) )
+   if( ! file.read( &_size ) )
+   {
+      std::cerr << "Unable to read the array size." << std::endl;
       return false;
-#endif
+   }
    if( _size < 0 )
    {
       std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
@@ -523,7 +510,7 @@ load( File& file )
       if( ! ArrayIO< Element, Device, Index >::load( file, this->data, this->size ) )
       {
          std::cerr << "I was not able to load " << this->getType()
-                   << " with size " << this->getSize() << std::endl;
+                    << " with size " << this -> getSize() << std::endl;
          return false;
       }
    }
@@ -537,16 +524,11 @@ bool
 Array< Element, Device, Index >::
 boundLoad( File& file )
 {
-   if( ! Object :: load( file ) )
+   if( ! Object::load( file ) )
       return false;
    Index _size;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< Index, Devices::Host >( &_size ) )
-      return false;
-#else
-   if( ! file. read( &_size ) )
+   if( ! file.read( &_size ) )
       return false;
-#endif
    if( _size < 0 )
    {
       std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
@@ -567,36 +549,13 @@ boundLoad( File& file )
       if( ! ArrayIO< Element, Device, Index >::load( file, this->data, this->size ) )
       {
          std::cerr << "I was not able to load " << this->getType()
-                   << " with size " << this->getSize() << std::endl;
+                    << " with size " << this -> getSize() << std::endl;
          return false;
       }
    }
    return true;
 }
 
-template< typename Element,
-          typename Device,
-          typename Index >
-bool
-Array< Element, Device, Index >::
-boundLoad( const String& fileName )
-{
-   File file;
-   if( ! file. open( fileName, tnlReadMode ) )
-   {
-      std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl;
-      return false;
-   }
-   if( ! this->boundLoad( file ) )
-      return false;
-   if( ! file. close() )
-   {
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-      return false;
-   }
-   return true;
-}
-
 template< typename Element,
           typename Device,
           typename Index >
@@ -614,7 +573,7 @@ std::ostream& operator << ( std::ostream& str, const Array< Element, Device, Ind
    {
       str << v.getElement( 0 );
       for( Index i = 1; i < v.getSize(); i++ )
-         str << ", " << v. getElement( i );
+         str << ", " << v.getElement( i );
    }
    str << " ]";
    return str;
diff --git a/src/TNL/Containers/CMakeLists.txt b/src/TNL/Containers/CMakeLists.txt
old mode 100755
new mode 100644
index d67b8f8b673bc08eeccdfb5a827d1ca016da957a..5ec11514d37db3dbbfbf00a952a909985f8de0c2
--- a/src/TNL/Containers/CMakeLists.txt
+++ b/src/TNL/Containers/CMakeLists.txt
@@ -3,12 +3,13 @@ ADD_SUBDIRECTORY( Algorithms )
 set( headers Array.h
              Array_impl.h
              ArrayIO.h
-             ArrayOperations.h
-             ArrayOperationsHost_impl.h
-             ArrayOperationsCuda_impl.h
              DynamicTypeTag.h
+             IndexedMap.h
+             IndexedMap_impl.h
              IndexedSet.h
              IndexedSet_impl.h
+             List.h
+             List_impl.h
              MultiArray.h
              MultiArray1D_impl.h
              MultiArray2D_impl.h
@@ -29,9 +30,6 @@ set( headers Array.h
              MultiVector2D_impl.h
              MultiVector3D_impl.h
              MultiVector4D_impl.h
-             VectorOperations.h
-             VectorOperationsHost_impl.h
-             VectorOperationsCuda_impl.h                                      
              SharedVector.h
              SharedVector_impl.h
              StaticVector.h 
@@ -46,7 +44,6 @@ set( common_SOURCES
      ${CURRENT_DIR}/MultiArray_impl.cpp
      ${CURRENT_DIR}/Array_impl.cpp
      ${CURRENT_DIR}/StaticArray_impl.cpp 
-     ${CURRENT_DIR}/VectorOperationsHost_impl.cpp
      ${CURRENT_DIR}/MultiVector_impl.cpp
      ${CURRENT_DIR}/SharedVector_impl.cpp
      ${CURRENT_DIR}/Vector_impl.cpp
@@ -56,26 +53,17 @@ set( common_SOURCES
 IF( BUILD_CUDA )
    set( tnl_containers_CUDA__SOURCES
         ${common_SOURCES}
-        ${CURRENT_DIR}/ArrayOperationsHost_impl.cu
-        ${CURRENT_DIR}/ArrayOperationsCuda_impl.cu
         ${CURRENT_DIR}/Array_impl.cu
         ${CURRENT_DIR}/SharedArray_impl.cu
         ${CURRENT_DIR}/MultiArray_impl.cu
         ${CURRENT_DIR}/StaticArray_impl.cu
-        ${CURRENT_DIR}/VectorOperationsCuda_impl.cu
         ${CURRENT_DIR}/Vector_impl.cu
         ${CURRENT_DIR}/StaticVector_impl.cu 
         PARENT_SCOPE )
-ELSE()
-   set( common_SOURCES
-        ${common_SOURCES}
-        ${CURRENT_DIR}/ArrayOperationsHost_impl.cpp
-        ${CURRENT_DIR}/ArrayOperationsCuda_impl.cpp
- )               
 ENDIF()    
 
 set( tnl_containers_SOURCES     
      ${common_SOURCES}
      PARENT_SCOPE )
                    
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Containers )
\ No newline at end of file
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Containers )
diff --git a/src/TNL/Containers/ConstSharedArray.h b/src/TNL/Containers/ConstSharedArray.h
index d9435f843739dd6e3b300a590adaabea198eeb99..ec719634f604e95ac92f06ca2259f6990972ba2e 100644
--- a/src/TNL/Containers/ConstSharedArray.h
+++ b/src/TNL/Containers/ConstSharedArray.h
@@ -91,13 +91,8 @@ class tnlConstSharedArray : public Object
     * Every time one touches this grid touches * size * sizeof( Real ) bytes are added
     * to transfered bytes in tnlStatistics.
     */
-#ifdef HAVE_NOT_CXX11
-   template< typename IndexType2 >
-   void touch( IndexType2 touches = 1 ) const;
-#else
    template< typename IndexType2 = Index >
    void touch( IndexType2 touches = 1 ) const;
-#endif
 
    //! Method for saving the object to a file as a binary data.
    bool save( File& file ) const;
diff --git a/src/TNL/Containers/ConstSharedArray_impl.h b/src/TNL/Containers/ConstSharedArray_impl.h
index d6a036459116503fd74f0ca505b2b9ca0ea42e44..fde53b35807267d85495f34d0d90ca38f69ba358 100644
--- a/src/TNL/Containers/ConstSharedArray_impl.h
+++ b/src/TNL/Containers/ConstSharedArray_impl.h
@@ -13,7 +13,7 @@
 #include <iostream>
 #include <TNL/File.h>
 #include <TNL/Containers/Array.h>
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Math.h>
 #include <TNL/param-types.h>
 
@@ -69,10 +69,10 @@ template< typename Element,
 void tnlConstSharedArray< Element, Device, Index > :: bind( const Element* data,
                                                             const Index size )
 {
-   Assert( size >= 0,
+   TNL_ASSERT( size >= 0,
               std::cerr << "You try to set size of tnlConstSharedArray to negative value."
                         << "New size: " << size << std::endl );
-   Assert( data != 0,
+   TNL_ASSERT( data != 0,
               std::cerr << "You try to use null pointer to data for tnlConstSharedArray." );
 
    this->size = size;
@@ -88,7 +88,7 @@ void tnlConstSharedArray< Element, Device, Index > :: bind( const Array& array,
                                                             IndexType size )
 {
    // TODO: This does not work for static arrays.
-   //tnlStaticAssert( Array::DeviceType::DeviceType == DeviceType::DeviceType,
+   //tnlStaticTNL_ASSERT( Array::DeviceType::DeviceType == DeviceType::DeviceType,
    //                 "Attempt to bind arrays between different devices." );
    this->data = &( array. getData()[ index ] );
    if( ! size )
@@ -130,11 +130,11 @@ template< typename Element,
           typename Index >
 Element tnlConstSharedArray< Element, Device, Index > :: getElement( Index i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 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 ArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
+   return Algorithms::ArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
 };
 
 template< typename Element,
@@ -143,12 +143,12 @@ template< typename Element,
 __cuda_callable__
 const Element& tnlConstSharedArray< Element, Device, Index > :: operator[] ( Index i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 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 Devices::CudaDevice
-   return ArrayOperations< Device >::getArrayElementReference( this->data, i );
+   return Algorithms::ArrayOperations< Device >::getArrayElementReference( this->data, i );
 };
 
 template< typename Element,
@@ -179,14 +179,13 @@ bool tnlConstSharedArray< Element, Device, Index > :: operator == ( const Array&
 {
    if( array. getSize() != this->getSize() )
       return false;
-   return ArrayOperations< Device,
-                              typename Array :: DeviceType > ::
-    template compareMemory< typename Array :: ElementType,
-                            Element,
-                            typename Array :: IndexType >
-                          ( this->getData(),
-                            array. getData(),
-                            array. getSize() );
+   return Algorithms::ArrayOperations< Device, typename Array :: DeviceType >::
+      template compareMemory< typename Array :: ElementType,
+                              Element,
+                              typename Array :: IndexType >
+                            ( this->getData(),
+                              array. getData(),
+                              array. getSize() );
 }
 
 template< typename Element,
@@ -229,15 +228,11 @@ template< typename Element,
           typename Index >
 bool tnlConstSharedArray< Element, Device, Index > :: save( File& file ) const
 {
-   Assert( this->size != 0,
+   TNL_ASSERT( this->size != 0,
               std::cerr << "You try to save empty array." );
    if( ! Object :: save( file ) )
       return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< const Index, Device >( &this->size ) )
-#else
    if( ! file. write( &this->size ) )
-#endif
       return false;
    if( ! file. write< Element, Device, Index >( this->data, this->size ) )
    {
diff --git a/src/TNL/Containers/IndexedMap.h b/src/TNL/Containers/IndexedMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c0e2d99471726fd08ee4c2529c8ca64ce63925d
--- /dev/null
+++ b/src/TNL/Containers/IndexedMap.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+                          IndexedMap.h  -  description
+                             -------------------
+    begin                : Feb 15, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <map>
+#include <stdexcept>
+
+namespace TNL {
+namespace Containers {
+
+template< typename Element,
+          typename Index,
+          typename Key >
+class IndexedMap
+{
+   public:
+
+   typedef Element   ElementType;
+   typedef Index     IndexType;
+   typedef Key       KeyType;
+
+   void reset();
+
+   IndexType getSize() const;
+
+   IndexType insert( const ElementType &data );
+
+   bool find( const ElementType &data, IndexType& index ) const;
+
+   template< typename ArrayType >
+   void toArray( ArrayType& array ) const;
+
+   const Element& getElement( KeyType key ) const;
+
+   Element& getElement( KeyType key );
+ 
+   void print( std::ostream& str ) const;
+
+   protected:
+
+   struct DataWithIndex
+   {
+      // This constructor is here only because of bug in g++, we might fix it later.
+      // http://stackoverflow.com/questions/22357887/comparing-two-mapiterators-why-does-it-need-the-copy-constructor-of-stdpair
+      DataWithIndex(){};
+ 
+      DataWithIndex( const DataWithIndex& d ) : data( d.data ), index( d.index) {}
+ 
+      explicit DataWithIndex( const Element data) : data( data ) {}
+
+      DataWithIndex( const Element data,
+                     const Index index) : data(data), index(index) {}
+
+      Element data;
+      Index index;
+   };
+
+   typedef std::map< Key, DataWithIndex >      STDMapType;
+   typedef typename STDMapType::value_type     STDMapValueType;
+   typedef typename STDMapType::const_iterator STDMapIteratorType;
+
+   STDMapType map;
+
+};
+
+template< typename Element,
+          typename Index,
+          typename Key >
+std::ostream& operator <<( std::ostream& str, IndexedMap< Element, Index, Key >& set );
+
+} // namespace Containers
+} // namespace TNL
+
+#include <TNL/Containers/IndexedMap_impl.h>
diff --git a/src/TNL/Containers/IndexedMap_impl.h b/src/TNL/Containers/IndexedMap_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2adb8872cd488d1ea2448024cff3521928b531a4
--- /dev/null
+++ b/src/TNL/Containers/IndexedMap_impl.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+                          IndexedMap_impl.h  -  description
+                             -------------------
+    begin                : Feb 15, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+namespace TNL {
+namespace Containers {
+
+template< typename Element,
+          typename Index,
+          typename Key >
+void IndexedMap< Element, Index, Key >::reset()
+{
+   map.clear();
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+Index IndexedMap< Element, Index, Key >::getSize() const
+{
+   return map.size();
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+Index IndexedMap< Element, Index, Key >::insert( const Element &data )
+{
+   STDMapIteratorType iter = map.insert( STDMapValueType( Key( data ),
+                                         DataWithIndex( data, getSize() ) ) ).first;
+   return iter->second.index;
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+bool IndexedMap< Element, Index, Key >::find( const Element &data, Index& index ) const
+{
+   STDMapIteratorType iter = map.find( Key( data ) );
+   if (iter == map.end())
+      return false;
+   index = iter->second.index;
+   return true;
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+   template<typename ArrayType>
+void IndexedMap< Element, Index, Key >::toArray( ArrayType& array ) const
+{
+   Assert( array.getSize() == getSize(),
+              std::cerr << "array.getSize() = " << array.getSize()
+                   << " getSize() = " << getSize() );
+
+   for( STDMapIteratorType iter = map.begin();
+        iter != map.end();
+        ++iter)
+      array[ iter->second.index ] = iter->second.data;
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+const Element& IndexedMap< Element, Index, Key >::getElement( KeyType key ) const
+{
+   return map[ key ];
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+Element& IndexedMap< Element, Index, Key >::getElement( KeyType key )
+{
+   return map[ key ];
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+void IndexedMap< Element, Index, Key >::print( std::ostream& str ) const
+{
+   STDMapIteratorType iter = map.begin();
+   str << iter->second.data;
+   iter++;
+   while( iter != map.end() )
+   {
+      str << ", " << iter->second.data;
+      iter++;
+   }
+}
+
+template< typename Element,
+          typename Index,
+          typename Key >
+std::ostream& operator<<( std::ostream& str, IndexedMap< Element, Index, Key >& set )
+{
+   set.print( str );
+   return str;
+}
+
+} // namespace Containers
+} // namespace TNL
diff --git a/src/TNL/Containers/IndexedSet.h b/src/TNL/Containers/IndexedSet.h
index e2c7e887ec534ba206c559aab73e684b14a793dd..087918a516999ec8a9d012c1aa7e98d2f412a02a 100644
--- a/src/TNL/Containers/IndexedSet.h
+++ b/src/TNL/Containers/IndexedSet.h
@@ -11,70 +11,45 @@
 #pragma once
 
 #include <map>
-#include <stdexcept>
+#include <ostream>
 
 namespace TNL {
 namespace Containers {
 
-template< typename Element,
-          typename Index,
-          typename Key >
+template< class Key,
+          class Index,
+          class Compare = std::less< Key >,
+          class Allocator = std::allocator< std::pair< const Key, Index > > >
 class IndexedSet
 {
-   public:
+protected:
+   using map_type = std::map< Key, Index, Compare, Allocator >;
+   map_type map;
 
-   typedef Element   ElementType;
-   typedef Index     IndexType;
-   typedef Key       KeyType;
+public:
+   using key_type = Key;
+   using index_type = Index;
+   using value_type = typename map_type::value_type;
+   using size_type = typename map_type::size_type;
 
-   void reset();
+   void clear();
 
-   IndexType getSize() const;
+   size_type size() const;
 
-   IndexType insert( const ElementType &data );
+   Index insert( const Key& key );
 
-   bool find( const ElementType &data, IndexType& index ) const;
+   bool find( const Key& key, Index& index ) const;
 
-   template< typename ArrayType >
-   void toArray( ArrayType& array ) const;
+   size_type count( const Key& key ) const;
 
-   const Element& getElement( KeyType key ) const;
+   size_type erase( const Key& key );
 
-   Element& getElement( KeyType key );
- 
    void print( std::ostream& str ) const;
-
-   protected:
-
-   struct DataWithIndex
-   {
-      // This constructor is here only because of bug in g++, we might fix it later.
-      // http://stackoverflow.com/questions/22357887/comparing-two-mapiterators-why-does-it-need-the-copy-constructor-of-stdpair
-      DataWithIndex(){};
- 
-      DataWithIndex( const DataWithIndex& d ) : data( d.data ), index( d.index) {}
- 
-      explicit DataWithIndex( const Element data) : data( data ) {}
-
-      DataWithIndex( const Element data,
-                     const Index index) : data(data), index(index) {}
-
-      Element data;
-      Index index;
-   };
-
-   typedef std::map< Key, DataWithIndex >      STDMapType;
-   typedef typename STDMapType::value_type     STDMapValueType;
-   typedef typename STDMapType::const_iterator STDMapIteratorType;
-
-   STDMapType map;
-
 };
 
 template< typename Element,
-          typename Index,
-          typename Key >
-std::ostream& operator <<( std::ostream& str, IndexedSet< Element, Index, Key >& set );
+          typename Index >
+std::ostream& operator <<( std::ostream& str, IndexedSet< Element, Index >& set );
 
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/IndexedSet_impl.h b/src/TNL/Containers/IndexedSet_impl.h
index 230d29303fbeb1eed17e5ca901253d06dbbd8cee..12ac49dba43c8da77a4f201451d96a9eba583e1a 100644
--- a/src/TNL/Containers/IndexedSet_impl.h
+++ b/src/TNL/Containers/IndexedSet_impl.h
@@ -10,85 +10,83 @@
 
 #pragma once
 
+#include <TNL/Containers/IndexedSet.h>
+
 namespace TNL {
 namespace Containers {
 
-template< typename Element,
-          typename Index,
-          typename Key >
-void IndexedSet< Element, Index, Key >::reset()
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+void
+IndexedSet< Key, Index, Compare, Allocator >::clear()
 {
    map.clear();
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-Index IndexedSet< Element, Index, Key >::getSize() const
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+typename IndexedSet< Key, Index, Compare, Allocator >::size_type
+IndexedSet< Key, Index, Compare, Allocator >::size() const
 {
    return map.size();
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-Index IndexedSet< Element, Index, Key >::insert( const Element &data )
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+Index
+IndexedSet< Key, Index, Compare, Allocator >::insert( const Key& key )
 {
-   STDMapIteratorType iter = map.insert( STDMapValueType( Key( data ),
-                                         DataWithIndex( data, getSize() ) ) ).first;
-   return iter->second.index;
+   auto iter = map.insert( value_type( key, size() ) ).first;
+   return iter->second;
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-bool IndexedSet< Element, Index, Key >::find( const Element &data, Index& index ) const
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+bool
+IndexedSet< Key, Index, Compare, Allocator >::find( const Key& key, Index& index ) const
 {
-   STDMapIteratorType iter = map.find( Key( data ) );
-   if (iter == map.end())
+   auto iter = map.find( Key( key ) );
+   if( iter == map.end() )
       return false;
    index = iter->second.index;
    return true;
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-   template<typename ArrayType>
-void IndexedSet< Element, Index, Key >::toArray( ArrayType& array ) const
-{
-   Assert( array.getSize() == getSize(),
-              std::cerr << "array.getSize() = " << array.getSize()
-                   << " getSize() = " << getSize() );
-
-   for( STDMapIteratorType iter = map.begin();
-        iter != map.end();
-        ++iter)
-      array[ iter->second.index ] = iter->second.data;
-}
-
-template< typename Element,
-          typename Index,
-          typename Key >
-const Element& IndexedSet< Element, Index, Key >::getElement( KeyType key ) const
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+typename IndexedSet< Key, Index, Compare, Allocator >::size_type
+IndexedSet< Key, Index, Compare, Allocator >::count( const Key& key ) const
 {
-   return map[ key ];
+   return map.count( key );
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-Element& IndexedSet< Element, Index, Key >::getElement( KeyType key )
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+typename IndexedSet< Key, Index, Compare, Allocator >::size_type
+IndexedSet< Key, Index, Compare, Allocator >::erase( const Key& key )
 {
-   return map[ key ];
+   return map.erase( key );
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-void IndexedSet< Element, Index, Key >::print( std::ostream& str ) const
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+void IndexedSet< Key, Index, Compare, Allocator >::print( std::ostream& str ) const
 {
-   STDMapIteratorType iter = map.begin();
+   auto iter = map.begin();
    str << iter->second.data;
    iter++;
    while( iter != map.end() )
@@ -98,10 +96,11 @@ void IndexedSet< Element, Index, Key >::print( std::ostream& str ) const
    }
 }
 
-template< typename Element,
-          typename Index,
-          typename Key >
-std::ostream& operator<<( std::ostream& str, IndexedSet< Element, Index, Key >& set )
+template< class Key,
+          class Index,
+          class Compare,
+          class Allocator >
+std::ostream& operator<<( std::ostream& str, IndexedSet< Key, Index, Compare, Allocator >& set )
 {
    set.print( str );
    return str;
diff --git a/src/TNL/List.h b/src/TNL/Containers/List.h
similarity index 83%
rename from src/TNL/List.h
rename to src/TNL/Containers/List.h
index 9d0f2cdb1a12a58087863576dfcfd1cbd793d117..0ec42106de2b49f5296e8a0aede1328715eea3f9 100644
--- a/src/TNL/List.h
+++ b/src/TNL/Containers/List.h
@@ -10,16 +10,17 @@
 
 #pragma once
 
-#include <TNL/Assert.h>
-#include <stdlib.h>
 #include <iostream>
+
+#include <TNL/Assert.h>
+#include <TNL/File.h>
 #include <TNL/String.h>
 #include <TNL/param-types.h>
 
 namespace TNL {
+namespace Containers {
 
-class File;
-template< class T > class DataElement;
+template< class T > class ListDataElement;
 
 //! Template for double linked lists
 /*! To acces elements in the list one can use method getSize() and
@@ -39,9 +40,7 @@ template< class T > class DataElement;
  */
 template< class T > class List
 {
-
    public:
-
       typedef T ElementType;
 
       //! Basic constructor
@@ -69,6 +68,10 @@ template< class T > class List
 
       const List& operator = ( const List& lst );
 
+      bool operator == ( const List& lst ) const;
+
+      bool operator != ( const List& lst ) const;
+
       //! Append new data element
       bool Append( const T& data );
 
@@ -112,57 +115,54 @@ template< class T > class List
       bool DeepLoad( File& file );
  
    protected:
-
       //! Pointer to the first element
-      DataElement< T >* first;
+      ListDataElement< T >* first;
 
       //! Pointer to the last element
       /*! We use pointer to last element while adding new element to keep order of elements
        */
-      DataElement< T >* last;
+      ListDataElement< T >* last;
 
       //! List size
       int size;
 
       //! Iterator
-      mutable DataElement< T >* iterator;
+      mutable ListDataElement< T >* iterator;
 
       //! Iterator index
       mutable int index;
- 
-
 };
 
 template< typename T > std::ostream& operator << ( std::ostream& str, const List< T >& list );
 
 //! Data element for List and mStack
-template< class T > class DataElement
+template< class T > class ListDataElement
 {
    //! Main data
    T data;
 
    //! Pointer to the next element
-   DataElement< T >* next;
+   ListDataElement< T >* next;
 
    //! Pointer to the previous element
-   DataElement< T >* previous;
+   ListDataElement< T >* previous;
 
    public:
    //! Basic constructor
-   DataElement()
+   ListDataElement()
       : next( 0 ),
         previous( 0 ){};
 
    //! Constructor with given data and possibly pointer to next element
-   DataElement( const T& dt,
-                   DataElement< T >* prv = 0,
-                   DataElement< T >* nxt = 0 )
+   ListDataElement( const T& dt,
+                    ListDataElement< T >* prv = 0,
+                    ListDataElement< T >* nxt = 0 )
       : data( dt ),
         next( nxt ),
         previous( prv ){};
 
    //! Destructor
-   ~DataElement(){};
+   ~ListDataElement(){};
 
    //! Return data for non-const instances
    T& Data() { return data; };
@@ -171,19 +171,19 @@ template< class T > class DataElement
    const T& Data() const { return data; };
 
    //! Return pointer to the next element for non-const instances
-   DataElement< T >*& Next() { return next; };
+   ListDataElement< T >*& Next() { return next; };
 
    //! Return pointer to the next element for const instances
-   const DataElement< T >* Next() const { return next; };
+   const ListDataElement< T >* Next() const { return next; };
 
    //! Return pointer to the previous element for non-const instances
-   DataElement< T >*& Previous() { return previous; };
+   ListDataElement< T >*& Previous() { return previous; };
 
    //! Return pointer to the previous element for const instances
-   const DataElement< T >* Previous() const { return previous; };
-
+   const ListDataElement< T >* Previous() const { return previous; };
 };
 
+} // namespace Containers
 } // namespace TNL
 
-#include <TNL/List_impl.h>
+#include <TNL/Containers/List_impl.h>
diff --git a/src/TNL/List_impl.h b/src/TNL/Containers/List_impl.h
similarity index 73%
rename from src/TNL/List_impl.h
rename to src/TNL/Containers/List_impl.h
index 389fb1732b63cea1cd95336a7a9ac5bf9f80dc5f..136f4cc986a35063a8be9f52ab4fa4e705b6c273 100644
--- a/src/TNL/List_impl.h
+++ b/src/TNL/Containers/List_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnlList_impl.h  -  description
+                          List_impl.h  -  description
                              -------------------
     begin                : Mar, 5 Apr 2016 12:46 PM
     copyright            : (C) 2016 by Tomas Oberhuber
@@ -10,9 +10,11 @@
 
 #pragma once
 
-#include <TNL/File.h>
+#include <TNL/Containers/List.h>
+#include <TNL/Math.h>
 
 namespace TNL {
+namespace Containers {
 
 template< typename T >
 List< T >::List()
@@ -54,8 +56,8 @@ int List< T >::getSize() const
 template< typename T >
 T& List< T >::operator[]( const int& ind )
 {
-   Assert( ind < size, );
-   int iter_dist = abs( index - ind );
+   TNL_ASSERT( ind < size, );
+   int iter_dist = TNL::abs( index - ind );
    if( ! iterator ||
        iter_dist > ind ||
        iter_dist > size - ind )
@@ -87,7 +89,7 @@ T& List< T >::operator[]( const int& ind )
          iterator = iterator -> Next();
          index ++;
       }
-      Assert( iterator, );
+      TNL_ASSERT( iterator, );
    }
    return iterator -> Data();
 };
@@ -105,20 +107,35 @@ const List< T >& List< T >::operator = ( const List& lst )
    return( *this );
 }
 
+template< typename T >
+bool List< T >::operator == ( const List& lst ) const
+{
+   if( this->getSize() != lst.getSize() )
+      return false;
+   for( int i = 0; i < this->getSize(); i++ )
+      if( (*this)[ i ] != lst[ i ] )
+         return false;
+   return true;
+}
+
+template< typename T >
+bool List< T >::operator != ( const List& lst ) const
+{
+   return ! operator==( lst );
+}
+
 template< typename T >
 bool List< T >::Append( const T& data )
 {
    if( ! first )
    {
-      Assert( ! last, );
-      first = last = new DataElement< T >( data );
-      if( ! first ) return false;
+      TNL_ASSERT( ! last, );
+      first = last = new ListDataElement< T >( data );
    }
    else
    {
-      DataElement< T >* new_element =  new DataElement< T >( data, last, 0 );
-      if( ! new_element ) return false;
-      Assert( last, );
+      ListDataElement< T >* new_element =  new ListDataElement< T >( data, last, 0 );
+      TNL_ASSERT( last, );
       last = last -> Next() = new_element;
    }
    size ++;
@@ -130,14 +147,12 @@ bool List< T >::Prepend( const T& data )
 {
    if( ! first )
    {
-      Assert( ! last, );
-      first = last = new DataElement< T >( data );
-      if( ! first ) return false;
+      TNL_ASSERT( ! last, );
+      first = last = new ListDataElement< T >( data );
    }
    else
    {
-      DataElement< T >* new_element =  new DataElement< T >( data, 0, first );
-      if( ! new_element ) return false;
+      ListDataElement< T >* new_element =  new ListDataElement< T >( data, 0, first );
       first = first -> Previous() = new_element;
    }
    size ++;
@@ -148,15 +163,14 @@ bool List< T >::Prepend( const T& data )
 template< typename T >
 bool List< T >::Insert( const T& data, const int& ind )
 {
-   Assert( ind <= size || ! size, );
+   TNL_ASSERT( ind <= size || ! size, );
    if( ind == 0 ) return Prepend( data );
    if( ind == size ) return Append( data );
    operator[]( ind );
-   DataElement< T >* new_el =
-      new DataElement< T >( data,
+   ListDataElement< T >* new_el =
+      new ListDataElement< T >( data,
                              iterator -> Previous(),
                              iterator );
-   if( ! new_el ) return false;
    iterator -> Previous() -> Next() = new_el;
    iterator -> Previous() = new_el;
    iterator = new_el;
@@ -189,9 +203,7 @@ template< typename T >
    template< typename Array >
 void List< T >::toArray( Array& array )
 {
-   Assert( this->getSize() <= array.getSize(),
-              std::cerr << "this->getSize() = " << this->getSize()
-                   << " array.getSize() = " << array.getSize() << std::endl; );
+   array.setSize( this->getSize() );
    for( int i = 0; i < this->getSize(); i++ )
       array[ i ] = ( *this )[ i ];
 }
@@ -200,7 +212,7 @@ template< typename T >
 void List< T >::Erase( const int& ind )
 {
    operator[]( ind );
-   DataElement< T >* tmp_it = iterator;
+   ListDataElement< T >* tmp_it = iterator;
    if( iterator -> Next() )
       iterator -> Next() -> Previous() = iterator -> Previous();
    if( iterator -> Previous() )
@@ -229,10 +241,10 @@ template< typename T >
 void List< T >::reset()
 {
    iterator = first;
-   DataElement< T >* tmp_it;
+   ListDataElement< T >* tmp_it;
    while( iterator )
    {
-      Assert( iterator, );
+      TNL_ASSERT( iterator, );
       tmp_it = iterator;
       iterator = iterator -> Next();
       delete tmp_it;
@@ -245,7 +257,7 @@ template< typename T >
 void List< T >::DeepEraseAll()
 {
    iterator = first;
-   DataElement< T >* tmp_it;
+   ListDataElement< T >* tmp_it;
    int i( 0 );
    while( iterator )
    {
@@ -262,59 +274,25 @@ void List< T >::DeepEraseAll()
 template< typename T >
 bool List< T >::Save( File& file ) const
 {
-#ifdef HAVE_NOT_CXX11
-   file.write< const int, Devices::Host >( &size );
-   for( int i = 0; i < size; i ++ )
-      if( ! file. write< int, Devices::Host, 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 List< T >::DeepSave( File& file ) const
 {
-#ifdef HAVE_NOT_CXX11
-   file. write< const int, Devices::Host >( &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 List< T >::Load( File& file )
 {
-#ifdef HAVE_NOT_CXX11
-   reset();
-   int _size;
-   file. read< int, Devices::Host >( &_size );
-   if( _size < 0 )
-   {
-      std::cerr << "The curve size is negative." << std::endl;
-      return false;
-   }
-   T t;
-   for( int i = 0; i < _size; i ++ )
-   {
-      if( ! file. read< T, Devices::Host >( &t ) )
-         return false;
-      Append( t );
-   }
-   return true;
-#else
    reset();
    int _size;
    file. read( &_size, 1 );
@@ -331,29 +309,11 @@ bool List< T >::Load( File& file )
       Append( t );
    }
    return true;
-#endif
 };
 
 template< typename T >
 bool List< T >::DeepLoad( File& file )
 {
-#ifdef HAVE_NOT_CXX11
-   reset();
-   int _size;
-   file. read< int, Devices::Host >( &_size );
-   if( _size < 0 )
-   {
-      std::cerr << "The list size is negative." << std::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 );
@@ -369,7 +329,6 @@ bool List< T >::DeepLoad( File& file )
       Append( t );
    }
    return true;
-#endif
 };
  
 template< typename T >
@@ -381,6 +340,5 @@ std::ostream& operator << ( std::ostream& str, const List< T >& list )
    return str;
 };
 
+} // namespace Containers
 } // namespace TNL
-
-
diff --git a/src/TNL/Containers/MultiArray.h b/src/TNL/Containers/MultiArray.h
index b062fb605109691bdb3e18ca3dbfe4b6a31f8ddd..f9de98a81f1141f244f9492a3d3cfeb3e85bbabe 100644
--- a/src/TNL/Containers/MultiArray.h
+++ b/src/TNL/Containers/MultiArray.h
@@ -18,7 +18,7 @@
 namespace TNL {
 namespace Containers {   
 
-template< int Dimensions, typename Element = double, typename Device = Devices::Host, typename Index = int >
+template< int Dimension, typename Element = double, typename Device = Devices::Host, typename Index = int >
 class MultiArray : public Array< Element, Device, Index >
 {
 };
@@ -27,7 +27,7 @@ template< typename Element, typename Device, typename Index >
 class MultiArray< 1, Element, Device, Index > : public Array< Element, Device, Index >
 {
    public:
-   enum { Dimensions = 1};
+   enum { Dimension = 1};
    typedef Element ElementType;
    typedef Device DeviceType;
    typedef Index IndexType;
@@ -45,9 +45,9 @@ class MultiArray< 1, Element, Device, Index > : public Array< Element, Device, I
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index iSize );
+   void setDimensions( const Index iSize );
 
-   bool setDimensions( const Containers::StaticVector< 1, Index >& dimensions );
+   void setDimensions( const Containers::StaticVector< 1, Index >& dimensions );
 
    __cuda_callable__ void getDimensions( Index& iSize ) const;
 
@@ -55,7 +55,7 @@ class MultiArray< 1, Element, Device, Index > : public Array< Element, Device, I
 
    //! Set dimensions of the array using another array as a template
    template< typename MultiArray >
-   bool setLike( const MultiArray& v );
+   void setLike( const MultiArray& v );
  
    void reset();
 
@@ -106,7 +106,7 @@ template< typename Element, typename Device, typename Index >
 class MultiArray< 2, Element, Device, Index > : public Array< Element, Device, Index >
 {
    public:
-   enum { Dimensions = 2 };
+   enum { Dimension = 2 };
    typedef Element ElementType;
    typedef Device DeviceType;
    typedef Index IndexType;
@@ -124,9 +124,9 @@ class MultiArray< 2, Element, Device, Index > : public Array< Element, Device, I
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index jSize, const Index iSize );
+   void setDimensions( const Index jSize, const Index iSize );
 
-   bool setDimensions( const Containers::StaticVector< 2, Index >& dimensions );
+   void setDimensions( const Containers::StaticVector< 2, Index >& dimensions );
 
    __cuda_callable__ void getDimensions( Index& jSize, Index& iSize ) const;
 
@@ -134,7 +134,7 @@ class MultiArray< 2, Element, Device, Index > : public Array< Element, Device, I
 
    //! Set dimensions of the array using another array as a template
    template< typename MultiArray >
-   bool setLike( const MultiArray& v );
+   void setLike( const MultiArray& v );
 
    void reset();
 
@@ -189,7 +189,7 @@ class MultiArray< 3, Element, Device, Index > : public Array< Element, Device, I
 {
    public:
 
-   enum { Dimensions = 3 };
+   enum { Dimension = 3 };
    typedef Element ElementType;
    typedef Device DeviceType;
    typedef Index IndexType;
@@ -207,9 +207,9 @@ class MultiArray< 3, Element, Device, Index > : public Array< Element, Device, I
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index k, const Index j, const Index iSize );
+   void setDimensions( const Index k, const Index j, const Index iSize );
 
-   bool setDimensions( const Containers::StaticVector< 3, Index >& dimensions );
+   void setDimensions( const Containers::StaticVector< 3, Index >& dimensions );
 
    __cuda_callable__ void getDimensions( Index& k, Index& j, Index& iSize ) const;
 
@@ -217,7 +217,7 @@ class MultiArray< 3, Element, Device, Index > : public Array< Element, Device, I
 
    //! Set dimensions of the array using another array as a template
    template< typename MultiArrayT >
-   bool setLike( const MultiArrayT& v );
+   void setLike( const MultiArrayT& v );
 
    void reset();
 
@@ -272,7 +272,7 @@ class MultiArray< 4, Element, Device, Index > : public Array< Element, Device, I
 {
    public:
 
-   enum { Dimensions = 4 };
+   enum { Dimension = 4 };
    typedef Element ElementType;
    typedef Device DeviceType;
    typedef Index IndexType;
@@ -290,9 +290,9 @@ class MultiArray< 4, Element, Device, Index > : public Array< Element, Device, I
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index l, const Index k, const Index j, const Index iSize );
+   void setDimensions( const Index l, const Index k, const Index j, const Index iSize );
 
-   bool setDimensions( const Containers::StaticVector< 4, Index >& dimensions );
+   void setDimensions( const Containers::StaticVector< 4, Index >& dimensions );
 
    __cuda_callable__ void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const;
 
@@ -300,7 +300,7 @@ class MultiArray< 4, Element, Device, Index > : public Array< Element, Device, I
 
    //! Set dimensions of the array using another array as a template
    template< typename MultiArrayT >
-   bool setLike( const MultiArrayT& v );
+   void setLike( const MultiArrayT& v );
 
    void reset();
 
diff --git a/src/TNL/Containers/MultiArray1D_impl.h b/src/TNL/Containers/MultiArray1D_impl.h
index 3a75633a99e3f37e9fead7af0489bd057738a462..d380aa831fdba0b302dee9743de4dbb7574d3d4c 100644
--- a/src/TNL/Containers/MultiArray1D_impl.h
+++ b/src/TNL/Containers/MultiArray1D_impl.h
@@ -22,7 +22,7 @@ template< typename Element, typename Device, typename Index >
 String MultiArray< 1, Element, Device, Index > :: getType()
 {
    return String( "Containers::MultiArray< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Element >() ) +
           String( ", " ) +
@@ -57,28 +57,28 @@ String MultiArray< 1, Element, Device, Index > :: getSerializationTypeVirtual()
 };
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 1, Element, Device, Index > :: setDimensions( const Index iSize )
+void MultiArray< 1, Element, Device, Index > :: setDimensions( const Index iSize )
 {
-   Assert( iSize > 0,
+   TNL_ASSERT( iSize > 0,
               std::cerr << "iSize = " << iSize );
    dimensions[ 0 ] = iSize;
-   return Array< Element, Device, Index >::setSize( iSize );
+   Array< Element, Device, Index >::setSize( iSize );
 }
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 1, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 1, Index >& dimensions )
+void MultiArray< 1, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 1, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0,
               std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
    this->dimensions = dimensions;
-   return Array< Element, Device, Index >::setSize( this->dimensions[ 0 ] );
+   Array< Element, Device, Index >::setSize( this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
    template< typename MultiArrayT >
-bool MultiArray< 1, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
+void MultiArray< 1, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
 {
-   return setDimensions( multiArray. getDimensions() );
+   setDimensions( multiArray. getDimensions() );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -106,7 +106,7 @@ template< typename Element, typename Device, typename Index >
 __cuda_callable__
 Index MultiArray< 1, Element, Device, Index > :: getElementIndex( const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ],
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ],
               std::cerr << "i = " << i << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ] );
    return i;
 }
@@ -142,7 +142,7 @@ template< typename Element, typename Device, typename Index >
 bool MultiArray< 1, Element, Device, Index > :: operator == ( const MultiArrayT& array ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -161,7 +161,7 @@ MultiArray< 1, Element, Device, Index >&
    MultiArray< 1, Element, Device, Index > :: operator = ( const MultiArray< 1, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -175,7 +175,7 @@ MultiArray< 1, Element, Device, Index >&
    MultiArray< 1, Element, Device, Index > :: operator = ( const MultiArrayT& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiArray2D_impl.h b/src/TNL/Containers/MultiArray2D_impl.h
index 83dca39ffb41b69887716c12020d0b5b20663753..3812429c8260d75874b74b249876a5d9e8e56cf1 100644
--- a/src/TNL/Containers/MultiArray2D_impl.h
+++ b/src/TNL/Containers/MultiArray2D_impl.h
@@ -22,7 +22,7 @@ template< typename Element, typename Device, typename Index >
 String MultiArray< 2, Element, Device, Index > :: getType()
 {
    return String( "Containers::MultiArray< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Element >() ) +
           String( ", " ) +
@@ -57,36 +57,36 @@ String MultiArray< 2, Element, Device, Index > :: getSerializationTypeVirtual()
 };
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 2, Element, Device, Index > :: setDimensions( const Index jSize,
+void MultiArray< 2, Element, Device, Index > :: setDimensions( const Index jSize,
                                                                   const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize );
 
    dimensions[ 0 ] = iSize;
    dimensions[ 1 ] = jSize;
-   return Array< Element, Device, Index > :: setSize( iSize * jSize );
+   Array< Element, Device, Index > :: setSize( iSize * jSize );
 }
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 2, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 2, Index >& dimensions )
+void MultiArray< 2, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 2, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
               std::cerr << "dimensions = " << dimensions );
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
     */
    this->dimensions. x() = dimensions. y();
    this->dimensions. y() = dimensions. x();
-   return Array< Element, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
+   Array< Element, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
    template< typename MultiArrayT >
-bool MultiArray< 2, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
+void MultiArray< 2, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
 {
-   return setDimensions( multiArray. getDimensions() );
+   setDimensions( multiArray. getDimensions() );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -115,7 +115,7 @@ template< typename Element, typename Device, typename Index >
 __cuda_callable__
 Index MultiArray< 2, Element, Device, Index > :: getElementIndex( const Index j, const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
               std::cerr << "i = " << i << " j = " << j << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ]
                    << " this->dimensions[ 1 ] = " << this->dimensions[ 1 ] );
    return j * this->dimensions[ 0 ] + i;
@@ -152,7 +152,7 @@ template< typename Element, typename Device, typename Index >
 bool MultiArray< 2, Element, Device, Index > :: operator == ( const MultiArrayT& array ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -171,7 +171,7 @@ MultiArray< 2, Element, Device, Index >&
    MultiArray< 2, Element, Device, Index > :: operator = ( const MultiArray< 2, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -185,7 +185,7 @@ MultiArray< 2, Element, Device, Index >&
    MultiArray< 2, Element, Device, Index > :: operator = ( const MultiArrayT& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiArray3D_impl.h b/src/TNL/Containers/MultiArray3D_impl.h
index fe7dd87412a8ed493b12b3265836f38da0c4a2d1..6e9fb9d9f2697d997ab32522257c2b1be23185bd 100644
--- a/src/TNL/Containers/MultiArray3D_impl.h
+++ b/src/TNL/Containers/MultiArray3D_impl.h
@@ -22,7 +22,7 @@ template< typename Element, typename Device, typename Index >
 String MultiArray< 3, Element, Device, Index > :: getType()
 {
    return String( "Containers::MultiArray< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Element >() ) +
           String( ", " ) +
@@ -57,11 +57,11 @@ String MultiArray< 3, Element, Device, Index > :: getSerializationTypeVirtual()
 };
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 3, Element, Device, Index > :: setDimensions( const Index kSize,
+void MultiArray< 3, Element, Device, Index > :: setDimensions( const Index kSize,
                                                                        const Index jSize,
                                                                        const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0 && kSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize
                    << "kSize = " << kSize );
@@ -69,13 +69,13 @@ bool MultiArray< 3, Element, Device, Index > :: setDimensions( const Index kSize
    dimensions[ 0 ] = iSize;
    dimensions[ 1 ] = jSize;
    dimensions[ 2 ] = kSize;
-   return Array< Element, Device, Index > :: setSize( iSize * jSize * kSize );
+   Array< Element, Device, Index > :: setSize( iSize * jSize * kSize );
 }
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 3, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 3, Index >& dimensions )
+void MultiArray< 3, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 3, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
               std::cerr << "dimensions = " << dimensions );
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
@@ -83,16 +83,16 @@ bool MultiArray< 3, Element, Device, Index > :: setDimensions( const Containers:
    this->dimensions. x() = dimensions. z();
    this->dimensions. y() = dimensions. y();
    this->dimensions. z() = dimensions. x();
-   return Array< Element, Device, Index > :: setSize( this->dimensions[ 2 ] *
-                                                          this->dimensions[ 1 ] *
-                                                          this->dimensions[ 0 ] );
+   Array< Element, Device, Index > :: setSize( this->dimensions[ 2 ] *
+                                               this->dimensions[ 1 ] *
+                                               this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
    template< typename MultiArrayT >
-bool MultiArray< 3, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
+void MultiArray< 3, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
 {
-   return setDimensions( multiArray. getDimensions() );
+   setDimensions( multiArray. getDimensions() );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -126,7 +126,7 @@ Index MultiArray< 3, Element, Device, Index > :: getElementIndex( const Index k,
                                                                      const Index j,
                                                                      const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] &&
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
               j >= 0 && j < this->dimensions[ 1 ] &&
               k >= 0 && k < this->dimensions[ 2 ],
               std::cerr << " i = " << i
@@ -176,7 +176,7 @@ template< typename Element, typename Device, typename Index >
 bool MultiArray< 3, Element, Device, Index > :: operator == ( const MultiArrayT& array ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -195,7 +195,7 @@ MultiArray< 3, Element, Device, Index >&
    MultiArray< 3, Element, Device, Index > :: operator = ( const MultiArray< 3, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -209,7 +209,7 @@ MultiArray< 3, Element, Device, Index >&
    MultiArray< 3, Element, Device, Index > :: operator = ( const MultiArrayT& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiArray4D_impl.h b/src/TNL/Containers/MultiArray4D_impl.h
index 7bcf10917dcb53ac5e047f6de0fd75bc872769ee..ec034b3d21b6b8de53fa3326c0f240a5a59a8884 100644
--- a/src/TNL/Containers/MultiArray4D_impl.h
+++ b/src/TNL/Containers/MultiArray4D_impl.h
@@ -23,7 +23,7 @@ template< typename Element, typename Device, typename Index >
 String MultiArray< 4, Element, Device, Index > :: getType()
 {
    return String( "Containers::MultiArray< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Element >() ) +
           String( ", " ) +
@@ -58,12 +58,12 @@ String MultiArray< 4, Element, Device, Index > :: getSerializationTypeVirtual()
 };
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 4, Element, Device, Index > :: setDimensions( const Index lSize,
+void MultiArray< 4, Element, Device, Index > :: setDimensions( const Index lSize,
                                                                        const Index kSize,
                                                                        const Index jSize,
                                                                        const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize
                    << "kSize = " << kSize
@@ -73,13 +73,13 @@ bool MultiArray< 4, Element, Device, Index > :: setDimensions( const Index lSize
    dimensions[ 1 ] = jSize;
    dimensions[ 2 ] = kSize;
    dimensions[ 3 ] = lSize;
-   return Array< Element, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
+   Array< Element, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
 }
 
 template< typename Element, typename Device, typename Index >
-bool MultiArray< 4, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 4, Index >& dimensions )
+void MultiArray< 4, Element, Device, Index > :: setDimensions( const Containers::StaticVector< 4, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
               std::cerr << "dimensions = " << dimensions );
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
@@ -88,17 +88,17 @@ bool MultiArray< 4, Element, Device, Index > :: setDimensions( const Containers:
    this->dimensions[ 1 ] = dimensions[ 2 ];
    this->dimensions[ 2 ] = dimensions[ 1 ];
    this->dimensions[ 3 ] = dimensions[ 0 ];
-   return Array< Element, Device, Index > :: setSize( this->dimensions[ 3 ] *
-                                                         this->dimensions[ 2 ] *
-                                                         this->dimensions[ 1 ] *
-                                                         this->dimensions[ 0 ] );
+   Array< Element, Device, Index > :: setSize( this->dimensions[ 3 ] *
+                                               this->dimensions[ 2 ] *
+                                               this->dimensions[ 1 ] *
+                                               this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
    template< typename MultiArrayT >
-bool MultiArray< 4, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
+void MultiArray< 4, Element, Device, Index > :: setLike( const MultiArrayT& multiArray )
 {
-   return setDimensions( multiArray. getDimensions() );
+   setDimensions( multiArray. getDimensions() );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -135,7 +135,7 @@ Index MultiArray< 4, Element, Device, Index > :: getElementIndex( const Index l,
                                                                      const Index j,
                                                                      const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] &&
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
               j >= 0 && j < this->dimensions[ 1 ] &&
               k >= 0 && k < this->dimensions[ 2 ] &&
               l >= 0 && l < this->dimensions[ 3 ],
@@ -191,7 +191,7 @@ template< typename Element, typename Device, typename Index >
 bool MultiArray< 4, Element, Device, Index > :: operator == ( const MultiArrayT& array ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -210,7 +210,7 @@ MultiArray< 4, Element, Device, Index >&
    MultiArray< 4, Element, Device, Index > :: operator = ( const MultiArray< 4, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
@@ -224,7 +224,7 @@ MultiArray< 4, Element, Device, Index >&
    MultiArray< 4, Element, Device, Index > :: operator = ( const MultiArrayT& array )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == array. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
               std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
                    << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiVector.h b/src/TNL/Containers/MultiVector.h
index ecd64f69f3fcb94e5058e9c124cfc6c56a7435dd..344321ce59fc10a6a04672631f5449c92cd3ca9d 100644
--- a/src/TNL/Containers/MultiVector.h
+++ b/src/TNL/Containers/MultiVector.h
@@ -17,7 +17,7 @@
 namespace TNL {
 namespace Containers {   
    
-template< int Dimensions, typename Real = double, typename Device = Devices::Host, typename Index = int >
+template< int Dimension, typename Real = double, typename Device = Devices::Host, typename Index = int >
 class MultiVector : public Vector< Real, Device, Index >
 {
 };
@@ -26,12 +26,12 @@ template< typename Real, typename Device, typename Index >
 class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index >
 {
    public:
-   enum { Dimensions = 1};
+   enum { Dimension = 1};
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef MultiVector< Dimensions, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimensions, Real, Devices::Cuda, Index > CudaType;
+   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
+   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
 
    MultiVector();
 
@@ -45,9 +45,9 @@ class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index iSize );
+   void setDimensions( const Index iSize );
 
-   bool setDimensions( const StaticVector< Dimensions, Index >& dimensions );
+   void setDimensions( const StaticVector< Dimension, Index >& dimensions );
 
    void getDimensions( Index& iSize ) const;
 
@@ -55,7 +55,7 @@ class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index
 
    //! Set dimensions of the Vector using another Vector as a template
    template< typename MultiVector >
-   bool setLike( const MultiVector& v );
+   void setLike( const MultiVector& v );
  
    Index getElementIndex( const Index i ) const;
 
@@ -100,19 +100,19 @@ class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index
 
    protected:
 
-   StaticVector< Dimensions, Index > dimensions;
+   StaticVector< Dimension, Index > dimensions;
 };
 
 template< typename Real, typename Device, typename Index >
 class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index >
 {
    public:
-   enum { Dimensions = 2 };
+   enum { Dimension = 2 };
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef MultiVector< Dimensions, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimensions, Real, Devices::Cuda, Index > CudaType;
+   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
+   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
 
    MultiVector();
 
@@ -126,9 +126,9 @@ class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index jSize, const Index iSize );
+   void setDimensions( const Index jSize, const Index iSize );
 
-   bool setDimensions( const StaticVector< 2, Index >& dimensions );
+   void setDimensions( const StaticVector< 2, Index >& dimensions );
 
    void getDimensions( Index& jSize, Index& iSize ) const;
 
@@ -136,7 +136,7 @@ class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index
 
    //! Set dimensions of the Vector using another Vector as a template
    template< typename MultiVector >
-   bool setLike( const MultiVector& v );
+   void setLike( const MultiVector& v );
 
    Index getElementIndex( const Index j, const Index i ) const;
 
@@ -189,12 +189,12 @@ class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index
 {
    public:
 
-   enum { Dimensions = 3 };
+   enum { Dimension = 3 };
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef MultiVector< Dimensions, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimensions, Real, Devices::Cuda, Index > CudaType;
+   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
+   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
 
    MultiVector();
 
@@ -208,9 +208,9 @@ class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index k, const Index j, const Index iSize );
+   void setDimensions( const Index k, const Index j, const Index iSize );
 
-   bool setDimensions( const StaticVector< 3, Index >& dimensions );
+   void setDimensions( const StaticVector< 3, Index >& dimensions );
 
    void getDimensions( Index& k, Index& j, Index& iSize ) const;
 
@@ -218,7 +218,7 @@ class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index
 
    //! Set dimensions of the Vector using another Vector as a template
    template< typename MultiVector >
-   bool setLike( const MultiVector& v );
+   void setLike( const MultiVector& v );
 
    Index getElementIndex( const Index k, const Index j, const Index i ) const;
 
@@ -271,12 +271,12 @@ class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index
 {
    public:
 
-   enum { Dimensions = 4 };
+   enum { Dimension = 4 };
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef MultiVector< Dimensions, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimensions, Real, Devices::Cuda, Index > CudaType;
+   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
+   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
 
    MultiVector();
 
@@ -290,9 +290,9 @@ class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index
 
    virtual String getSerializationTypeVirtual() const;
 
-   bool setDimensions( const Index l, const Index k, const Index j, const Index iSize );
+   void setDimensions( const Index l, const Index k, const Index j, const Index iSize );
 
-   bool setDimensions( const StaticVector< 4, Index >& dimensions );
+   void setDimensions( const StaticVector< 4, Index >& dimensions );
 
    void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const;
 
@@ -300,7 +300,7 @@ class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index
 
    //! Set dimensions of the Vector using another Vector as a template
    template< typename MultiVector >
-   bool setLike( const MultiVector& v );
+   void setLike( const MultiVector& v );
 
    Index getElementIndex( const Index l, const Index k, const Index j, const Index i ) const;
 
diff --git a/src/TNL/Containers/MultiVector1D_impl.h b/src/TNL/Containers/MultiVector1D_impl.h
index 3fc35fee6cde0af4599dfe609b33d2bb589a7529..eb0e3109f636fbe5c45f396dc63a9e3deb8d0561 100644
--- a/src/TNL/Containers/MultiVector1D_impl.h
+++ b/src/TNL/Containers/MultiVector1D_impl.h
@@ -22,7 +22,7 @@ template< typename Real, typename Device, typename Index >
 String MultiVector< 1, Real, Device, Index > :: getType()
 {
    return String( "Containers::MultiVector< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Real >() ) +
           String( ", " ) +
@@ -57,28 +57,28 @@ String MultiVector< 1, Real, Device, Index > :: getSerializationTypeVirtual() co
 };
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: setDimensions( const Index iSize )
+void MultiVector< 1, Real, Device, Index > :: setDimensions( const Index iSize )
 {
-   Assert( iSize > 0,
+   TNL_ASSERT( iSize > 0,
               std::cerr << "iSize = " << iSize );
    dimensions[ 0 ] = iSize;
-   return Vector< Real, Device, Index > :: setSize( iSize );
+   Vector< Real, Device, Index > :: setSize( iSize );
 }
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: setDimensions( const StaticVector< Dimensions, Index >& dimensions )
+void MultiVector< 1, Real, Device, Index > :: setDimensions( const StaticVector< Dimension, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0,
               std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
    this->dimensions = dimensions;
-   return Vector< Real, Device, Index > :: setSize( this->dimensions[ 0 ] );
+   Vector< Real, Device, Index > :: setSize( this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
    template< typename MultiVectorT >
-bool MultiVector< 1, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
+void MultiVector< 1, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
 {
-   return setDimensions( multiVector. getDimensions() );
+   setDimensions( multiVector. getDimensions() );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -96,7 +96,7 @@ const StaticVector< 1, Index >& MultiVector< 1, Real, Device, Index > :: getDime
 template< typename Real, typename Device, typename Index >
 Index MultiVector< 1, Real, Device, Index > :: getElementIndex( const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ],
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ],
               std::cerr << "i = " << i
                    << "this->dimensions[ 0 ] " << this->dimensions[ 0 ] );
    return i;
@@ -132,7 +132,7 @@ template< typename Real, typename Device, typename Index >
 bool MultiVector< 1, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
                    << "First Vector name dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second Vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -151,7 +151,7 @@ MultiVector< 1, Real, Device, Index >&
    MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVector< 1, Real, Device, Index >& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -165,7 +165,7 @@ MultiVector< 1, Real, Device, Index >&
    MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiVector2D_impl.h b/src/TNL/Containers/MultiVector2D_impl.h
index dd95fdb28ae65eccc65dc70852bc059889255ed6..7eb483e9ed122ecff6a6e4d67ce2d9d25d06fb15 100644
--- a/src/TNL/Containers/MultiVector2D_impl.h
+++ b/src/TNL/Containers/MultiVector2D_impl.h
@@ -22,7 +22,7 @@ template< typename Real, typename Device, typename Index >
 String MultiVector< 2, Real, Device, Index > :: getType()
 {
    return String( "Containers::MultiVector< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Real >() ) +
           String( ", " ) +
@@ -57,32 +57,32 @@ String MultiVector< 2, Real, Device, Index > :: getSerializationTypeVirtual() co
 };
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: setDimensions( const Index jSize,
-                                                                       const Index iSize )
+void MultiVector< 2, Real, Device, Index > :: setDimensions( const Index jSize,
+                                                             const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize );
 
    dimensions[ 0 ] = iSize;
    dimensions[ 1 ] = jSize;
-   return Vector< Real, Device, Index > :: setSize( iSize * jSize );
+   Vector< Real, Device, Index > :: setSize( iSize * jSize );
 }
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: setDimensions( const StaticVector< 2, Index >& dimensions )
+void MultiVector< 2, Real, Device, Index > :: setDimensions( const StaticVector< 2, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
               std::cerr << "dimensions = " << dimensions );
    this->dimensions = dimensions;
-   return Vector< Real, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
+   Vector< Real, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
    template< typename MultiVectorT >
-bool MultiVector< 2, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
+void MultiVector< 2, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
 {
-   return setDimensions( multiVector. getDimensions() );
+   setDimensions( multiVector. getDimensions() );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -101,7 +101,7 @@ const StaticVector< 2, Index >& MultiVector< 2, Real, Device, Index > :: getDime
 template< typename Real, typename Device, typename Index >
 Index MultiVector< 2, Real, Device, Index > :: getElementIndex( const Index j, const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
               std::cerr << "i = " << i
                    << "j = " << j
                    << "this->dimensions[ 0 ] = " << this->dimensions[ 0 ]
@@ -139,7 +139,7 @@ template< typename Real, typename Device, typename Index >
 bool MultiVector< 2, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -158,7 +158,7 @@ MultiVector< 2, Real, Device, Index >&
    MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVector< 2, Real, Device, Index >& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -172,7 +172,7 @@ MultiVector< 2, Real, Device, Index >&
    MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiVector3D_impl.h b/src/TNL/Containers/MultiVector3D_impl.h
index 7d551b923b766ffe27e105c0e58dc707ea832419..24d92f0e262a32e77b8c375f07f13bb40742d5e5 100644
--- a/src/TNL/Containers/MultiVector3D_impl.h
+++ b/src/TNL/Containers/MultiVector3D_impl.h
@@ -22,7 +22,7 @@ template< typename Real, typename Device, typename Index >
 String MultiVector< 3, Real, Device, Index > :: getType()
 {
    return String( "Containers::MultiVector< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Real >() ) +
           String( ", " ) +
@@ -57,11 +57,11 @@ String MultiVector< 3, Real, Device, Index > :: getSerializationTypeVirtual() co
 };
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: setDimensions( const Index kSize,
-                                                                       const Index jSize,
-                                                                       const Index iSize )
+void MultiVector< 3, Real, Device, Index > :: setDimensions( const Index kSize,
+                                                             const Index jSize,
+                                                             const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0 && kSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize
                    << "kSize = " << kSize );
@@ -73,21 +73,21 @@ bool MultiVector< 3, Real, Device, Index > :: setDimensions( const Index kSize,
 }
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: setDimensions( const StaticVector< 3, Index >& dimensions )
+void MultiVector< 3, Real, Device, Index > :: setDimensions( const StaticVector< 3, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
               std::cerr << "dimensions = " << dimensions );
    this->dimensions = dimensions;
-   return Vector< Real, Device, Index > :: setSize( this->dimensions[ 2 ] *
-                                                          this->dimensions[ 1 ] *
-                                                          this->dimensions[ 0 ] );
+   Vector< Real, Device, Index > :: setSize( this->dimensions[ 2 ] *
+                                             this->dimensions[ 1 ] *
+                                             this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
    template< typename MultiVectorT >
-bool MultiVector< 3, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
+void MultiVector< 3, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
 {
-   return setDimensions( multiVector. getDimensions() );
+   setDimensions( multiVector. getDimensions() );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -111,7 +111,7 @@ Index MultiVector< 3, Real, Device, Index > :: getElementIndex( const Index k,
                                                                      const Index j,
                                                                      const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] &&
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
               j >= 0 && j < this->dimensions[ 1 ] &&
               k >= 0 && k < this->dimensions[ 2 ],
               std::cerr << " i = " << i
@@ -159,7 +159,7 @@ template< typename Real, typename Device, typename Index >
 bool MultiVector< 3, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -178,7 +178,7 @@ MultiVector< 3, Real, Device, Index >&
    MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVector< 3, Real, Device, Index >& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -192,7 +192,7 @@ MultiVector< 3, Real, Device, Index >&
    MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/MultiVector4D_impl.h b/src/TNL/Containers/MultiVector4D_impl.h
index a4ad6262b5e296c6239327c5ea055835aa55a71d..f9c883371f53439e9921280a844cb6c21175ff19 100644
--- a/src/TNL/Containers/MultiVector4D_impl.h
+++ b/src/TNL/Containers/MultiVector4D_impl.h
@@ -22,7 +22,7 @@ template< typename Real, typename Device, typename Index >
 String MultiVector< 4, Real, Device, Index > :: getType()
 {
    return String( "Containers::MultiVector< ") +
-          String( Dimensions ) +
+          String( Dimension ) +
           String( ", " ) +
           String( TNL::getType< Real >() ) +
           String( ", " ) +
@@ -57,12 +57,12 @@ String MultiVector< 4, Real, Device, Index > :: getSerializationTypeVirtual() co
 };
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: setDimensions( const Index lSize,
-                                                                       const Index kSize,
-                                                                       const Index jSize,
-                                                                       const Index iSize )
+void MultiVector< 4, Real, Device, Index > :: setDimensions( const Index lSize,
+                                                             const Index kSize,
+                                                             const Index jSize,
+                                                             const Index iSize )
 {
-   Assert( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
+   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
               std::cerr << "iSize = " << iSize
                    << "jSize = " << jSize
                    << "kSize = " << kSize
@@ -72,26 +72,26 @@ bool MultiVector< 4, Real, Device, Index > :: setDimensions( const Index lSize,
    dimensions[ 1 ] = jSize;
    dimensions[ 2 ] = kSize;
    dimensions[ 3 ] = lSize;
-   return Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
+   Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
 }
 
 template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: setDimensions( const StaticVector< 4, Index >& dimensions )
+void MultiVector< 4, Real, Device, Index > :: setDimensions( const StaticVector< 4, Index >& dimensions )
 {
-   Assert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
+   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
               std::cerr << "dimensions = " << dimensions );
    this->dimensions = dimensions;
-   return Vector< Real, Device, Index > :: setSize( this->dimensions[ 3 ] *
-                                                          this->dimensions[ 2 ] *
-                                                          this->dimensions[ 1 ] *
-                                                          this->dimensions[ 0 ] );
+   Vector< Real, Device, Index > :: setSize( this->dimensions[ 3 ] *
+                                             this->dimensions[ 2 ] *
+                                             this->dimensions[ 1 ] *
+                                             this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
    template< typename MultiVectorT >
-bool MultiVector< 4, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
+void MultiVector< 4, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
 {
-   return setDimensions( multiVector. getDimensions() );
+   setDimensions( multiVector. getDimensions() );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -118,7 +118,7 @@ Index MultiVector< 4, Real, Device, Index > :: getElementIndex( const Index l,
                                                                           const Index j,
                                                                           const Index i ) const
 {
-   Assert( i >= 0 && i < this->dimensions[ 0 ] &&
+   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
               j >= 0 && j < this->dimensions[ 1 ] &&
               k >= 0 && k < this->dimensions[ 2 ] &&
               l >= 0 && l < this->dimensions[ 3 ],
@@ -176,7 +176,7 @@ template< typename Real, typename Device, typename Index >
 bool MultiVector< 4, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -195,7 +195,7 @@ MultiVector< 4, Real, Device, Index >&
    MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVector< 4, Real, Device, Index >& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
@@ -209,7 +209,7 @@ MultiVector< 4, Real, Device, Index >&
    MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
 {
    // TODO: Static assert on dimensions
-   Assert( this->getDimensions() == vector. getDimensions(),
+   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
               std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
                    << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
                    << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
diff --git a/src/TNL/Containers/SharedArray.h b/src/TNL/Containers/SharedArray.h
index 0c4684830b9addd29e55a8d37fcbf34ceda9aafe..4feaf7862bd7fc35a17e35e69a6230466d0cdf49 100644
--- a/src/TNL/Containers/SharedArray.h
+++ b/src/TNL/Containers/SharedArray.h
@@ -44,17 +44,25 @@ class SharedArray : public Object
    typedef SharedArray< Element, Devices::Host, Index > HostType;
    typedef SharedArray< Element, Devices::Cuda, Index > CudaType;
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedArray();
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedArray( Element* _data,
                    const Index _size );
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedArray( Array< Element, Device, Index >& array );
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedArray( SharedArray< Element, Device, Index >& array );
 
    static String getType();
@@ -113,6 +121,7 @@ class SharedArray : public Object
 
    __cuda_callable__ Element* getData();
 
+
    /*!
     * Returns true if non-zero size is set.
     */
@@ -123,13 +132,8 @@ class SharedArray : public Object
     * Every time one touches this grid touches * size * sizeof( Real ) bytes are added
     * to transfered bytes in tnlStatistics.
     */
-#ifdef HAVE_NOT_CXX11
-   template< typename IndexType2 >
-   void touch( IndexType2 touches = 1 ) const;
-#else
    template< typename IndexType2 = Index >
    void touch( IndexType2 touches = 1 ) const;
-#endif
 
    //! Method for saving the object to a file as a binary data.
    bool save( File& file ) const;
@@ -149,6 +153,7 @@ class SharedArray : public Object
    Element* data;
 };
 
+
 template< typename Element, typename Device, typename Index >
 std::ostream& operator << ( std::ostream& str, const SharedArray< Element, Device, Index >& v );
 
diff --git a/src/TNL/Containers/SharedArray_impl.h b/src/TNL/Containers/SharedArray_impl.h
index 60eeec9359382d5035f62cdb227bf3ab2a3fd273..44eb48a02177e01f4ed553fab33f5bfa6dd40100 100644
--- a/src/TNL/Containers/SharedArray_impl.h
+++ b/src/TNL/Containers/SharedArray_impl.h
@@ -14,17 +14,20 @@
 #include <TNL/File.h>
 #include <TNL/Containers/Array.h>
 #include <TNL/Containers/StaticArray.h>
-#include <TNL/Containers/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Math.h>
 #include <TNL/param-types.h>
 
 namespace TNL {
 namespace Containers {   
 
+
 template< typename Element,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedArray< Element, Device, Index >::SharedArray()
 : size( 0 ), data( 0 )
 {
@@ -33,7 +36,9 @@ SharedArray< Element, Device, Index >::SharedArray()
 template< typename Element,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedArray< Element, Device, Index >::SharedArray( Element* _data,
                                                           const Index _size )
 {
@@ -43,7 +48,9 @@ SharedArray< Element, Device, Index >::SharedArray( Element* _data,
 template< typename Element,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedArray< Element, Device, Index >::SharedArray( Array< Element, Device, Index >& array )
 {
    this->bind( array );
@@ -52,7 +59,9 @@ SharedArray< Element, Device, Index >::SharedArray( Array< Element, Device, Inde
 template< typename Element,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedArray< Element, Device, Index >::SharedArray( SharedArray< Element, Device, Index >& array )
 {
    this->bind( array );
@@ -104,10 +113,10 @@ __cuda_callable__
 void SharedArray< Element, Device, Index > :: bind( Element* data,
                                                        const Index size )
 {
-   Assert( size >= 0,
+   TNL_ASSERT( size >= 0,
               std::cerr << "You try to set size of SharedArray to negative value."
                         << "New size: " << size << std::endl );
-   Assert( data != 0,
+   TNL_ASSERT( data != 0,
               std::cerr << "You try to use null pointer to data for SharedArray." );
 
    this->size = size;
@@ -123,7 +132,7 @@ void SharedArray< Element, Device, Index > :: bind( Array& array,
                                                        IndexType index,
                                                        IndexType size )
 {
-   //tnlStaticAssert( Array::DeviceType::DeviceType == DeviceType::DeviceType,
+   //tnlStaticTNL_ASSERT( Array::DeviceType::DeviceType == DeviceType::DeviceType,
    //                 "Attempt to bind arrays between different devices." );
    // TODO: fix this - it does nto work with StaticArray
    this->data = &( array. getData()[ index ] );
@@ -187,11 +196,11 @@ template< typename Element,
           typename Index >
 void SharedArray< Element, Device, Index > :: setElement( const Index& i, const Element& x )
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 0 <= i && i < this->getSize(),
               std::cerr << "Wrong index for setElement method in SharedArray "
                         << " index is " << i
                         << " and array size is " << this->getSize() );
-   return ArrayOperations< Device >::setMemoryElement( & ( this->data[ i ] ), x );
+   return Algorithms::ArrayOperations< Device >::setMemoryElement( & ( this->data[ i ] ), x );
 };
 
 template< typename Element,
@@ -199,11 +208,11 @@ template< typename Element,
           typename Index >
 Element SharedArray< Element, Device, Index > :: getElement( const Index& i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 0 <= i && i < this->getSize(),
               std::cerr << "Wrong index for getElement method in SharedArray "
                         << " index is " << i
                         << " and array size is " << this->getSize() );
-   return ArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
+   return Algorithms::ArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
 };
 
 template< typename Element,
@@ -212,7 +221,7 @@ template< typename Element,
 __cuda_callable__
 Element& SharedArray< Element, Device, Index > :: operator[] ( const Index& i )
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 0 <= i && i < this->getSize(),
               std::cerr << "Wrong index for operator[] in SharedArray "
                         << " index is " << i
                         << " and array size is " << this->getSize() );
@@ -225,7 +234,7 @@ template< typename Element,
 __cuda_callable__
 const Element& SharedArray< Element, Device, Index > :: operator[] ( const Index& i ) const
 {
-   Assert( 0 <= i && i < this->getSize(),
+   TNL_ASSERT( 0 <= i && i < this->getSize(),
               std::cerr << "Wrong index for operator[] in SharedArray "
                         << " index is " << i
                         << " and array size is " << this->getSize() );
@@ -238,16 +247,16 @@ template< typename Element,
 SharedArray< Element, Device, Index >&
     SharedArray< Element, Device, Index > :: operator = ( const SharedArray< Element, Device, Index >& array )
 {
-   Assert( array. getSize() == this->getSize(),
+   TNL_ASSERT( array. getSize() == this->getSize(),
               std::cerr << "Source size: " << array. getSize() << std::endl
                         << "Target size: " << this->getSize() << std::endl );
-   ArrayOperations< Device > ::
-   template copyMemory< Element,
-                        Element,
-                        Index >
-                       ( this->getData(),
-                         array. getData(),
-                         array. getSize() );
+   Algorithms::ArrayOperations< Device > ::
+      template copyMemory< Element,
+                           Element,
+                           Index >
+                          ( this->getData(),
+                            array. getData(),
+                            array. getSize() );
    return ( *this );
 };
 
@@ -257,17 +266,16 @@ template< typename Element,
    template< typename Array >
 SharedArray< Element, Device, Index >& SharedArray< Element, Device, Index > :: operator = ( const Array& array )
 {
-   Assert( array. getSize() == this->getSize(),
+   TNL_ASSERT( array. getSize() == this->getSize(),
               std::cerr << "Source size: " << array. getSize() << std::endl
                         << "Target size: " << this->getSize() << std::endl );
-   ArrayOperations< typename Array :: DeviceType,
-                       Device > ::
-    template copyMemory< Element,
-                         typename Array :: ElementType,
-                         typename Array :: IndexType >
-                       ( this->getData(),
-                         array. getData(),
-                         array. getSize() );
+   Algorithms::ArrayOperations< typename Array::DeviceType, Device >::
+      template copyMemory< Element,
+                           typename Array :: ElementType,
+                           typename Array :: IndexType >
+                         ( this->getData(),
+                           array. getData(),
+                           array. getSize() );
    return ( *this );
 };
 
@@ -279,14 +287,13 @@ bool SharedArray< Element, Device, Index > :: operator == ( const Array& array )
 {
    if( array. getSize() != this->getSize() )
       return false;
-   return ArrayOperations< Device,
-                              typename Array :: DeviceType > ::
-    template compareMemory< typename Array :: ElementType,
-                            Element,
-                            typename Array :: IndexType >
-                          ( this->getData(),
-                            array. getData(),
-                            array. getSize() );
+   return Algorithms::ArrayOperations< Device, typename Array::DeviceType >::
+      template compareMemory< typename Array :: ElementType,
+                              Element,
+                              typename Array :: IndexType >
+                            ( this->getData(),
+                              array. getData(),
+                              array. getSize() );
 }
 
 template< typename Element,
@@ -303,8 +310,8 @@ template< typename Element,
           typename Index >
 void SharedArray< Element, Device, Index > :: setValue( const Element& e )
 {
-   Assert( this->size != 0, );
-   ArrayOperations< Device >::template setMemory< Element, Index >
+   TNL_ASSERT( this->size != 0, );
+   Algorithms::ArrayOperations< Device >::template setMemory< Element, Index >
                               ( this->getData(), e, this->getSize() );
 
 }
@@ -312,6 +319,7 @@ void SharedArray< Element, Device, Index > :: setValue( const Element& e )
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__ 
 const Element* SharedArray< Element, Device, Index > :: getData() const
 {
    return this->data;
@@ -320,6 +328,7 @@ const Element* SharedArray< Element, Device, Index > :: getData() const
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__ 
 Element* SharedArray< Element, Device, Index > :: getData()
 {
    return this->data;
@@ -348,15 +357,11 @@ template< typename Element,
           typename Index >
 bool SharedArray< Element, Device, Index > :: save( File& file ) const
 {
-   Assert( this->size != 0,
+   TNL_ASSERT( this->size != 0,
               std::cerr << "You try to save empty array." << std::endl );
    if( ! Object :: save( file ) )
       return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< const Index, Devices::Host >( &this->size ) )
-#else
    if( ! file. write( &this->size ) )
-#endif
       return false;
    if( ! file. write< Element, Device, Index >( this->data, this->size ) )
    {
@@ -382,13 +387,8 @@ bool SharedArray< Element, Device, Index > :: load( File& file )
    if( ! Object :: load( file ) )
       return false;
    Index _size;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< Index, Devices::Host >( &_size ) )
-      return false;
-#else
    if( ! file. read( &_size, 1 ) )
       return false;
-#endif
    if( _size != this->size )
    {
       std::cerr << "Error: The size " << _size << " of the data to be load is different from the " <<
diff --git a/src/TNL/Containers/SharedVector.h b/src/TNL/Containers/SharedVector.h
index c4a22ded20ba860502c408c3ddd038966146064c..6526f1b4b7aac8241325f70a866a803b20e98158 100644
--- a/src/TNL/Containers/SharedVector.h
+++ b/src/TNL/Containers/SharedVector.h
@@ -39,17 +39,25 @@ class SharedVector : public Containers::SharedArray< Real, Device, Index >
    typedef SharedVector< Real, Devices::Cuda, Index > CudaType;
 
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedVector();
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedVector( Real* data,
                     const Index size );
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedVector( Vector< Real, Device, Index >& vector );
 
+   #ifndef HAVE_MIC
    __cuda_callable__
+   #endif
    SharedVector( SharedVector< Real, Device, Index >& vector );
 
    static String getType();
diff --git a/src/TNL/Containers/SharedVector_impl.h b/src/TNL/Containers/SharedVector_impl.h
index d086bfc6426a2d6e6ceffda40c73beeb67ad7613..446612f133408a6560b2e89dcaf60e4d35259ed6 100644
--- a/src/TNL/Containers/SharedVector_impl.h
+++ b/src/TNL/Containers/SharedVector_impl.h
@@ -10,7 +10,8 @@
 
 #pragma once
 
-#include <TNL/Containers/VectorOperations.h>
+#include <TNL/Containers/SharedVector.h>
+#include <TNL/Containers/Algorithms/VectorOperations.h>
 
 namespace TNL {
 namespace Containers {   
@@ -18,7 +19,9 @@ namespace Containers {
 template< typename Real,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedVector< Real, Device, Index >::SharedVector()
 {
 }
@@ -26,7 +29,9 @@ SharedVector< Real, Device, Index >::SharedVector()
 template< typename Real,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedVector< Real, Device, Index >::SharedVector( Real* data,
                                                          const Index size )
 : Containers::SharedArray< Real, Device, Index >( data, size )
@@ -36,7 +41,9 @@ SharedVector< Real, Device, Index >::SharedVector( Real* data,
 template< typename Real,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedVector< Real, Device, Index >::SharedVector( Vector< Real, Device, Index >& vector )
 : Containers::SharedArray< Real, Device, Index >( vector )
 {
@@ -45,7 +52,9 @@ SharedVector< Real, Device, Index >::SharedVector( Vector< Real, Device, Index >
 template< typename Real,
           typename Device,
           typename Index >
+#ifndef HAVE_MIC
 __cuda_callable__
+#endif
 SharedVector< Real, Device, Index >::SharedVector( SharedVector< Real, Device, Index >& vector )
 : Containers::SharedArray< Real, Device, Index >( vector )
 {
@@ -92,7 +101,7 @@ template< typename Real,
 void SharedVector< Real, Device, Index >::addElement( const IndexType i,
                                                          const RealType& value )
 {
-   VectorOperations< Device >::addElement( *this, i, value );
+   Algorithms::VectorOperations< Device >::addElement( *this, i, value );
 }
 
 template< typename Real,
@@ -102,7 +111,7 @@ void SharedVector< Real, Device, Index >::addElement( const IndexType i,
                                                          const RealType& value,
                                                          const RealType& thisElementMultiplicator )
 {
-   VectorOperations< Device >::addElement( *this, i, value, thisElementMultiplicator );
+   Algorithms::VectorOperations< Device >::addElement( *this, i, value, thisElementMultiplicator );
 }
 
 template< typename Real,
@@ -169,7 +178,7 @@ template< typename Real,
           typename Index >
 SharedVector< Real, Device, Index >& SharedVector< Real, Device, Index > :: operator *= ( const RealType& c )
 {
-   VectorOperations< Device >::vectorScalarMultiplication( *this, c );
+   Algorithms::VectorOperations< Device >::vectorScalarMultiplication( *this, c );
    return *this;
 }
 
@@ -178,7 +187,7 @@ template< typename Real,
           typename Index >
 SharedVector< Real, Device, Index >& SharedVector< Real, Device, Index > :: operator /= ( const RealType& c )
 {
-   VectorOperations< Device >::vectorScalarMultiplication( *this, 1.0/ c );
+   Algorithms::VectorOperations< Device >::vectorScalarMultiplication( *this, 1.0/ c );
    return *this;
 }
 
@@ -187,7 +196,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: max() const
 {
-   return VectorOperations< Device > :: getVectorMax( *this );
+   return Algorithms::VectorOperations< Device > :: getVectorMax( *this );
 }
 
 template< typename Real,
@@ -195,7 +204,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: min() const
 {
-   return VectorOperations< Device > :: getVectorMin( *this );
+   return Algorithms::VectorOperations< Device > :: getVectorMin( *this );
 }
 
 
@@ -204,7 +213,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: absMax() const
 {
-   return VectorOperations< Device > :: getVectorAbsMax( *this );
+   return Algorithms::VectorOperations< Device > :: getVectorAbsMax( *this );
 }
 
 template< typename Real,
@@ -212,7 +221,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: absMin() const
 {
-   return VectorOperations< Device > :: getVectorAbsMin( *this );
+   return Algorithms::VectorOperations< Device > :: getVectorAbsMin( *this );
 }
 
 template< typename Real,
@@ -220,7 +229,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: lpNorm( const Real& p ) const
 {
-   return VectorOperations< Device > :: getVectorLpNorm( *this, p );
+   return Algorithms::VectorOperations< Device > :: getVectorLpNorm( *this, p );
 }
 
 
@@ -229,7 +238,7 @@ template< typename Real,
           typename Index >
 Real SharedVector< Real, Device, Index > :: sum() const
 {
-   return VectorOperations< Device > :: getVectorSum( *this );
+   return Algorithms::VectorOperations< Device > :: getVectorSum( *this );
 }
 
 
@@ -239,7 +248,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceMax( const Vector& v ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceMax( *this, v );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceMax( *this, v );
 }
 
 
@@ -249,7 +258,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceMin( const Vector& v ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceMin( *this, v );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceMin( *this, v );
 }
 
 
@@ -259,7 +268,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceAbsMax( const Vector& v ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceAbsMax( *this, v );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceAbsMax( *this, v );
 }
 
 template< typename Real,
@@ -268,7 +277,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceAbsMin( const Vector& v ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceAbsMin( *this, v );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceAbsMin( *this, v );
 }
 
 template< typename Real,
@@ -277,7 +286,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceLpNorm( const Vector& v, const Real& p ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceLpNorm( *this, v, p );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceLpNorm( *this, v, p );
 }
 
 
@@ -287,7 +296,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: differenceSum( const Vector& v ) const
 {
-   return VectorOperations< Device > :: getVectorDifferenceSum( *this, v );
+   return Algorithms::VectorOperations< Device > :: getVectorDifferenceSum( *this, v );
 }
 
 
@@ -296,7 +305,7 @@ template< typename Real,
           typename Index >
 void SharedVector< Real, Device, Index > :: scalarMultiplication( const Real& alpha )
 {
-   VectorOperations< Device > :: vectorScalarMultiplication( *this, alpha );
+   Algorithms::VectorOperations< Device > :: vectorScalarMultiplication( *this, alpha );
 }
 
 
@@ -306,7 +315,7 @@ template< typename Real,
 template< typename Vector >
 Real SharedVector< Real, Device, Index > :: scalarProduct( const Vector& v )
 {
-   return VectorOperations< Device > :: getScalarProduct( *this, v );
+   return Algorithms::VectorOperations< Device > :: getScalarProduct( *this, v );
 }
 
 template< typename Real,
@@ -317,7 +326,7 @@ void SharedVector< Real, Device, Index > :: addVector( const Vector& x,
                                                           const Real& alpha,
                                                           const Real& thisMultiplicator )
 {
-   VectorOperations< Device > :: addVector( *this, x, alpha, thisMultiplicator );
+   Algorithms::VectorOperations< Device > :: addVector( *this, x, alpha, thisMultiplicator );
 }
 
 template< typename Real,
@@ -332,7 +341,7 @@ addVectors( const Vector& v1,
             const Real& multiplicator2,
             const Real& thisMultiplicator )
 {
-   VectorOperations< Device >::addVectors( *this, v1, multiplicator1, v2, multiplicator2, thisMultiplicator );
+   Algorithms::VectorOperations< Device >::addVectors( *this, v1, multiplicator1, v2, multiplicator2, thisMultiplicator );
 }
 
 template< typename Real,
@@ -340,7 +349,7 @@ template< typename Real,
           typename Index >
 void SharedVector< Real, Device, Index > :: computePrefixSum()
 {
-   VectorOperations< Device >::computePrefixSum( *this, 0, this->getSize() );
+   Algorithms::VectorOperations< Device >::computePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
@@ -349,7 +358,7 @@ template< typename Real,
 void SharedVector< Real, Device, Index > :: computePrefixSum( const IndexType begin,
                                                                  const IndexType end )
 {
-   VectorOperations< Device >::computePrefixSum( *this, begin, end );
+   Algorithms::VectorOperations< Device >::computePrefixSum( *this, begin, end );
 }
 
 template< typename Real,
@@ -357,7 +366,7 @@ template< typename Real,
           typename Index >
 void SharedVector< Real, Device, Index > :: computeExclusivePrefixSum()
 {
-   VectorOperations< Device >::computeExclusivePrefixSum( *this, 0, this->getSize() );
+   Algorithms::VectorOperations< Device >::computeExclusivePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
@@ -366,7 +375,7 @@ template< typename Real,
 void SharedVector< Real, Device, Index > :: computeExclusivePrefixSum( const IndexType begin,
                                                                           const IndexType end )
 {
-   VectorOperations< Device >::computeExclusivePrefixSum( *this, begin, end );
+   Algorithms::VectorOperations< Device >::computeExclusivePrefixSum( *this, begin, end );
 }
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Containers/StaticArray.h b/src/TNL/Containers/StaticArray.h
index 63ac6be40399a2ccec1948fc54bfaf5a32181ade..32f4528dbf5aaedf1c9561c849e42747bd5f1e4a 100644
--- a/src/TNL/Containers/StaticArray.h
+++ b/src/TNL/Containers/StaticArray.h
@@ -16,10 +16,6 @@
 namespace TNL {
 namespace Containers {   
 
-//! Aliases for the coordinates
-// TODO: Remove this - it is here only because of some legact code
-enum { tnlX = 0, tnlY, tnlZ };
-
 template< int Size, typename Element >
 class StaticArray
 {
@@ -31,6 +27,9 @@ class StaticArray
    __cuda_callable__
    inline StaticArray();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    inline StaticArray( const Element v[ Size ] );
 
@@ -91,7 +90,6 @@ class StaticArray
 
    protected:
    Element data[ Size ];
-
 };
 
 template< typename Element >
@@ -105,6 +103,9 @@ class StaticArray< 1, Element >
    __cuda_callable__
    inline StaticArray();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    inline StaticArray( const Element v[ size ] );
 
@@ -186,6 +187,9 @@ class StaticArray< 2, Element >
    __cuda_callable__
    inline StaticArray();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    inline StaticArray( const Element v[ size ] );
 
@@ -278,6 +282,9 @@ class StaticArray< 3, Element >
    __cuda_callable__
    inline StaticArray();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    inline StaticArray( const Element v[ size ] );
 
@@ -365,7 +372,6 @@ class StaticArray< 3, Element >
 
    protected:
    Element data[ size ];
-
 };
 
 template< int Size, typename Element >
@@ -378,4 +384,3 @@ std::ostream& operator << ( std::ostream& str, const StaticArray< Size, Element
 #include <TNL/Containers/StaticArray1D_impl.h>
 #include <TNL/Containers/StaticArray2D_impl.h>
 #include <TNL/Containers/StaticArray3D_impl.h>
-
diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h
index 9165686cf1298c81538822994d38b7d25d3b55d4..a23849cca338b609ad65a3c68d99d0c712ccf099 100644
--- a/src/TNL/Containers/StaticArray1D_impl.h
+++ b/src/TNL/Containers/StaticArray1D_impl.h
@@ -11,6 +11,7 @@
 #pragma once
 
 #include <TNL/param-types.h>
+#include <TNL/Containers/StaticArray.h>
 
 namespace TNL {
 namespace Containers {   
@@ -22,6 +23,7 @@ inline StaticArray< 1, Element >::StaticArray()
 }
 
 template< typename Element >
+   template< typename _unused >
 __cuda_callable__
 inline StaticArray< 1, Element >::StaticArray( const Element v[ size ] )
 {
@@ -77,8 +79,8 @@ template< typename Element >
 __cuda_callable__
 inline const Element& StaticArray< 1, Element >::operator[]( int i ) const
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -86,8 +88,8 @@ template< typename Element >
 __cuda_callable__
 inline Element& StaticArray< 1, Element >::operator[]( int i )
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -171,11 +173,7 @@ bool StaticArray< 1, Element >::save( File& file ) const
 template< typename Element >
 bool StaticArray< 1, Element >::load( File& file)
 {
-#ifdef HAVE_NOT_CXX11
-   if( ! file.read< Element, Devices::Host, int >( data, size ) )
-#else
    if( ! file.read( data, size ) )
-#endif
    {
       std::cerr << "Unable to read " << getType() << "." << std::endl;
       return false;
diff --git a/src/TNL/Containers/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h
index fd9e53b5cfca4ebde411996f1d80eea4a83d1873..44ed90b0a6c42f5d9ef28cc2a72959a8c17e586e 100644
--- a/src/TNL/Containers/StaticArray2D_impl.h
+++ b/src/TNL/Containers/StaticArray2D_impl.h
@@ -12,6 +12,7 @@
 
 #include <TNL/param-types.h>
 #include <TNL/Math.h>
+#include <TNL/Containers/StaticArray.h>
 
 namespace TNL {
 namespace Containers {   
@@ -23,6 +24,7 @@ inline StaticArray< 2, Element >::StaticArray()
 }
 
 template< typename Element >
+   template< typename _unused >
 __cuda_callable__
 inline StaticArray< 2, Element >::StaticArray( const Element v[ size ] )
 {
@@ -89,8 +91,8 @@ template< typename Element >
 __cuda_callable__
 inline const Element& StaticArray< 2, Element >::operator[]( int i ) const
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -98,8 +100,8 @@ template< typename Element >
 __cuda_callable__
 inline Element& StaticArray< 2, Element >::operator[]( int i )
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
diff --git a/src/TNL/Containers/StaticArray3D_impl.h b/src/TNL/Containers/StaticArray3D_impl.h
index d11b05bbcc8699ab6d9aff1beab9f51e2bb278c7..4e89783ca84dd6279930cd92f21526a34aa54cb3 100644
--- a/src/TNL/Containers/StaticArray3D_impl.h
+++ b/src/TNL/Containers/StaticArray3D_impl.h
@@ -11,6 +11,8 @@
 #pragma once
 
 #include <TNL/param-types.h>
+#include <TNL/Math.h>
+#include <TNL/Containers/StaticArray.h>
 
 namespace TNL {
 namespace Containers {   
@@ -22,6 +24,7 @@ inline StaticArray< 3, Element >::StaticArray()
 }
 
 template< typename Element >
+   template< typename _unused >
 __cuda_callable__
 inline StaticArray< 3, Element >::StaticArray( const Element v[ size ] )
 {
@@ -68,6 +71,7 @@ String StaticArray< 3, Element >::getType()
 }
 
 template< typename Element >
+__cuda_callable__
 inline int StaticArray< 3, Element >::getSize() const
 {
    return size;
@@ -91,8 +95,8 @@ template< typename Element >
 __cuda_callable__
 inline const Element& StaticArray< 3, Element >::operator[]( int i ) const
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -100,8 +104,8 @@ template< typename Element >
 __cuda_callable__
 inline Element& StaticArray< 3, Element >::operator[]( int i )
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
diff --git a/src/TNL/Containers/StaticArray_impl.h b/src/TNL/Containers/StaticArray_impl.h
index 5e573623602592833e42e7654112f958749fee80..9be36764a5b8e316900db466fa1a284fcf0ac4ab 100644
--- a/src/TNL/Containers/StaticArray_impl.h
+++ b/src/TNL/Containers/StaticArray_impl.h
@@ -12,6 +12,7 @@
 
 #include <TNL/param-types.h>
 #include <TNL/Math.h>
+#include <TNL/Containers/StaticArray.h>
 
 namespace TNL {
 namespace Containers {   
@@ -23,6 +24,7 @@ inline StaticArray< Size, Element >::StaticArray()
 };
 
 template< int Size, typename Element >
+   template< typename _unused >
 __cuda_callable__
 inline StaticArray< Size, Element >::StaticArray( const Element v[ Size ] )
 {
@@ -81,8 +83,8 @@ template< int Size, typename Element >
 __cuda_callable__
 inline const Element& StaticArray< Size, Element >::operator[]( int i ) const
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -90,8 +92,8 @@ template< int Size, typename Element >
 __cuda_callable__
 inline Element& StaticArray< Size, Element >::operator[]( int i )
 {
-   Assert( i >= 0 && i < size,
-            std::cerr << "i = " << i << " size = " << size << std::endl; );
+   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
+   TNL_ASSERT_LT( i, size, "Element index is out of bounds." );
    return data[ i ];
 }
 
@@ -203,12 +205,9 @@ std::ostream& StaticArray< Size, Element >::write( std::ostream& str, const char
 template< int Size, typename Element >
 std::ostream& operator << ( std::ostream& str, const StaticArray< Size, Element >& a )
 {
-   a.write( str, "," );
-   /*for( int i = 0; i < Size - 1; i ++ )
-   {
-      str << a[ i ] << ", ";
-   }
-   str << a[ Size - 1 ];*/
+   str << "[ ";
+   a.write( str, ", " );
+   str << " ]";
    return str;
 };
 
diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h
index d3a10c9865bed431f05c6d30990b27c9fa14e018..ca410edfefaf94e4d74b3c84b91b72fad0c4d07d 100644
--- a/src/TNL/Containers/StaticVector.h
+++ b/src/TNL/Containers/StaticVector.h
@@ -11,12 +11,13 @@
 #pragma once
 
 #include <TNL/Containers/StaticArray.h>
+#include <TNL/Config/ParameterContainer.h>
 
 namespace TNL {
 namespace Containers {   
 
 template< int Size, typename Real = double >
-class StaticVector : public Containers::StaticArray< Size, Real >
+class StaticVector : public StaticArray< Size, Real >
 {
    public:
    typedef Real RealType;
@@ -26,6 +27,9 @@ class StaticVector : public Containers::StaticArray< Size, Real >
    __cuda_callable__
    StaticVector();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    StaticVector( const Real v[ Size ] );
 
@@ -37,6 +41,9 @@ class StaticVector : public Containers::StaticArray< Size, Real >
    __cuda_callable__
    StaticVector( const StaticVector< Size, Real >& v );
 
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );      
+
    static String getType();
 
    //! Adding operator
@@ -82,13 +89,33 @@ class StaticVector : public Containers::StaticArray< Size, Real >
    template< typename OtherReal >
    __cuda_callable__
    operator StaticVector< Size, OtherReal >() const;
- 
+
    __cuda_callable__
    ThisType abs() const;
+
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< Size, Real >& operator=( const StaticVector< Size, Real >& vector )
+   {
+      StaticArray< Size, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< Size, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< Size, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
-class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
+class StaticVector< 1, Real > : public StaticArray< 1, Real >
 {
    public:
    typedef Real RealType;
@@ -98,6 +125,12 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
    __cuda_callable__
    StaticVector();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
+   __cuda_callable__
+   StaticVector( const Real v[ 1 ] );
+
    //! This sets all vector components to v
    __cuda_callable__
    StaticVector( const Real& v );
@@ -105,6 +138,9 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
    //! Copy constructor
    __cuda_callable__
    StaticVector( const StaticVector< 1, Real >& v );
+   
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );      
 
    static String getType();
 
@@ -154,10 +190,30 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
  
    __cuda_callable__
    ThisType abs() const;
+
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 1, Real >& operator=( const StaticVector< 1, Real >& vector )
+   {
+      StaticArray< 1, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 1, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 1, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
-class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
+class StaticVector< 2, Real > : public StaticArray< 2, Real >
 {
    public:
    typedef Real RealType;
@@ -167,6 +223,9 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
    __cuda_callable__
    StaticVector();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    StaticVector( const Real v[ 2 ] );
 
@@ -180,6 +239,9 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
    //! Copy constructor
    __cuda_callable__
    StaticVector( const StaticVector< 2, Real >& v );
+   
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );      
 
    static String getType();
 
@@ -229,10 +291,30 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
  
    __cuda_callable__
    ThisType abs() const;
+
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 2, Real >& operator=( const StaticVector< 2, Real >& vector )
+   {
+      StaticArray< 2, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 2, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 2, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
-class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
+class StaticVector< 3, Real > : public StaticArray< 3, Real >
 {
    public:
    typedef Real RealType;
@@ -242,6 +324,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
    __cuda_callable__
    StaticVector();
 
+   // Note: the template avoids ambiguity of overloaded functions with literal 0 and pointer
+   // reference: https://stackoverflow.com/q/4610503
+   template< typename _unused = void >
    __cuda_callable__
    StaticVector( const Real v[ 3 ] );
 
@@ -255,6 +340,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
    //! Copy constructor
    __cuda_callable__
    StaticVector( const StaticVector< 3, Real >& v );
+   
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );      
 
    static String getType();
 
@@ -304,11 +392,31 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
  
    __cuda_callable__
    ThisType abs() const;
+
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 3, Real >& operator=( const StaticVector< 3, Real >& vector )
+   {
+      StaticArray< 3, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 3, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 3, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
-template< int Size, typename Real >
+template< int Size, typename Real, typename Scalar >
 __cuda_callable__
-StaticVector< Size, Real > operator * ( const Real& c, const StaticVector< Size, Real >& u );
+StaticVector< Size, Real > operator * ( const Scalar& c, const StaticVector< Size, Real >& u );
 
 template< int Size, typename Real >
 __cuda_callable__
@@ -336,21 +444,21 @@ StaticVector< 3, Real > VectorProduct( const StaticVector< 3, Real >& u,
    p[ 1 ] = u[ 2 ] * v[ 0 ] - u[ 0 ] * v[ 2 ];
    p[ 2 ] = u[ 0 ] * v[ 1 ] - u[ 1 ] * v[ 0 ];
    return p;
-};
+}
 
 template< typename Real >
 Real tnlScalarProduct( const StaticVector< 2, Real >& u,
                        const StaticVector< 2, Real >& v )
 {
    return u[ 0 ] * v[ 0 ] + u[ 1 ] * v[ 1 ];
-};
+}
 
 template< typename Real >
 Real tnlScalarProduct( const StaticVector< 3, Real >& u,
                        const StaticVector< 3, Real >& v )
 {
    return u[ 0 ] * v[ 0 ] + u[ 1 ] * v[ 1 ] + u[ 2 ] * v[ 2 ];
-};
+}
 
 template< typename Real >
 Real tnlTriangleArea( const StaticVector< 2, Real >& a,
@@ -366,8 +474,8 @@ Real tnlTriangleArea( const StaticVector< 2, Real >& a,
    u2. z() = 0;
 
    const StaticVector< 3, Real > v = VectorProduct( u1, u2 );
-   return 0.5 * ::sqrt( tnlScalarProduct( v, v ) );
-};
+   return 0.5 * TNL::sqrt( tnlScalarProduct( v, v ) );
+}
 
 template< typename Real >
 Real tnlTriangleArea( const StaticVector< 3, Real >& a,
@@ -377,14 +485,14 @@ Real tnlTriangleArea( const StaticVector< 3, Real >& a,
    StaticVector< 3, Real > u1, u2;
    u1. x() = b. x() - a. x();
    u1. y() = b. y() - a. y();
-   u1. z() = 0.0;
+   u1. z() = b. z() - a. z();
    u2. x() = c. x() - a. x();
    u2. y() = c. y() - a. y();
-   u2. z() = 0;
+   u2. z() = c. z() - a. z();
 
    const StaticVector< 3, Real > v = VectorProduct( u1, u2 );
-   return 0.5 * ::sqrt( tnlScalarProduct( v, v ) );
-};
+   return 0.5 * TNL::sqrt( tnlScalarProduct( v, v ) );
+}
 
 } // namespace Containers
 } // namespace TNL
diff --git a/src/TNL/Containers/StaticVector1D_impl.h b/src/TNL/Containers/StaticVector1D_impl.h
index a8e4151a352a71b455f7404977d3e347874a46d2..3127a621910111ff1490ccdc94675c8e737d7fc8 100644
--- a/src/TNL/Containers/StaticVector1D_impl.h
+++ b/src/TNL/Containers/StaticVector1D_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once 
 
+#include <TNL/Containers/StaticVector.h>
+
 namespace TNL {
 namespace Containers {   
 
@@ -19,20 +21,37 @@ StaticVector< 1, Real >::StaticVector()
 {
 }
 
+template< typename Real >
+   template< typename _unused >
+__cuda_callable__
+StaticVector< 1, Real >::StaticVector( const Real v[ 1 ] )
+: StaticArray< 1, Real >( v )
+{
+}
+
 template< typename Real >
 __cuda_callable__
 StaticVector< 1, Real >::StaticVector( const Real& v )
-: Containers::StaticArray< 1, Real >( v )
+: StaticArray< 1, Real >( v )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 1, Real >::StaticVector( const StaticVector< 1, Real >& v )
-: Containers::StaticArray< 1, Real >( v )
+: StaticArray< 1, Real >( v )
 {
 }
 
+template< typename Real >
+bool
+StaticVector< 1, Real >::setup( const Config::ParameterContainer& parameters,
+                                const String& prefix )
+{
+   this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" );
+   return true;
+}
+
 template< typename Real >
 String StaticVector< 1, Real >::getType()
 {
@@ -148,6 +167,14 @@ StaticVector< 1, Real >::abs() const
    return StaticVector< 1, Real >( TNL::abs( this->data[ 0 ] ) );
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+StaticVector< 1, Real >::lpNorm( const Real& p ) const
+{
+   return TNL::abs( this->data[ 0 ] );
+}
+
 #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION
 
 #ifndef HAVE_CUDA
diff --git a/src/TNL/Containers/StaticVector2D_impl.h b/src/TNL/Containers/StaticVector2D_impl.h
index 60b0ffa452d7c3eb8028b4f504d11b39645de5ef..d66979bf7a3be3bed89929b3d84cdf5da61199d4 100644
--- a/src/TNL/Containers/StaticVector2D_impl.h
+++ b/src/TNL/Containers/StaticVector2D_impl.h
@@ -10,7 +10,7 @@
 
 #pragma once 
 
-#include <TNL/Math.h>
+#include <TNL/Containers/StaticVector.h>
 
 namespace TNL {
 namespace Containers {   
@@ -22,33 +22,44 @@ StaticVector< 2, Real >::StaticVector()
 }
 
 template< typename Real >
+   template< typename _unused >
 __cuda_callable__
 StaticVector< 2, Real >::StaticVector( const Real v[ 2 ] )
-: Containers::StaticArray< 2, Real >( v )
+: StaticArray< 2, Real >( v )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 2, Real >::StaticVector( const Real& v )
-: Containers::StaticArray< 2, Real >( v )
+: StaticArray< 2, Real >( v )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 2, Real >::StaticVector( const Real& v1, const Real& v2 )
-: Containers::StaticArray< 2, Real >( v1, v2 )
+: StaticArray< 2, Real >( v1, v2 )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 2, Real >::StaticVector( const StaticVector< 2, Real >& v )
-: Containers::StaticArray< 2, Real >( v )
+: StaticArray< 2, Real >( v )
 {
 }
 
+template< typename Real >
+bool
+StaticVector< 2, Real >::setup( const Config::ParameterContainer& parameters,
+                                const String& prefix )
+{
+   this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" );
+   this->data[ 1 ] = parameters.getParameter< double >( prefix + "1" );
+   return true;
+}
+
 template< typename Real >
 String StaticVector< 2, Real >::getType()
 {
@@ -173,10 +184,23 @@ __cuda_callable__
 StaticVector< 2, Real >
 StaticVector< 2, Real >::abs() const
 {
-   return StaticVector< 2, Real >( ::abs( this->data[ 0 ] ),
-                                      ::abs( this->data[ 1 ] ) );
+   return StaticVector< 2, Real >( TNL::abs( this->data[ 0 ] ),
+                                   TNL::abs( this->data[ 1 ] ) );
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+StaticVector< 2, Real >::lpNorm( const Real& p ) const
+{
+   if( p == 1.0 )
+      return TNL::abs( this->data[ 0 ] ) + TNL::abs( this->data[ 1 ] );
+   if( p == 2.0 )
+      return TNL::sqrt( this->data[ 0 ] * this->data[ 0 ] + 
+                        this->data[ 1 ] * this->data[ 1 ] );
+   return TNL::pow( TNL::pow( TNL::abs( this->data[ 0 ] ), p ) +
+                    TNL::pow( TNL::abs( this->data[ 1 ] ), p ), 1.0 / p ); 
+}
 
 #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -195,3 +219,4 @@ extern template class StaticVector< 2, long double >;
 
 } // namespace Containers
 } // namespace TNL
+
diff --git a/src/TNL/Containers/StaticVector3D_impl.h b/src/TNL/Containers/StaticVector3D_impl.h
index 91de4c92266453c7b5660b64644c6e5a89f3e049..d01e82077afd4feba62657d769803a68e1fe8fa1 100644
--- a/src/TNL/Containers/StaticVector3D_impl.h
+++ b/src/TNL/Containers/StaticVector3D_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Containers/StaticVector.h>
+
 namespace TNL {
 namespace Containers {   
 
@@ -20,31 +22,43 @@ StaticVector< 3, Real >::StaticVector()
 }
 
 template< typename Real >
+   template< typename _unused >
 __cuda_callable__
 StaticVector< 3, Real >::StaticVector( const Real v[ 3 ] )
-: Containers::StaticArray< 3, Real >( v )
+: StaticArray< 3, Real >( v )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 3, Real >::StaticVector( const Real& v )
-: Containers::StaticArray< 3, Real >( v )
+: StaticArray< 3, Real >( v )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 3, Real >::StaticVector( const Real& v1, const Real& v2, const Real& v3 )
-: Containers::StaticArray< 3, Real >( v1, v2, v3 )
+: StaticArray< 3, Real >( v1, v2, v3 )
 {
 }
 
 template< typename Real >
 __cuda_callable__
 StaticVector< 3, Real >::StaticVector( const StaticVector< 3, Real >& v )
-: Containers::StaticArray< 3, Real >( v )
+: StaticArray< 3, Real >( v )
+{
+}
+
+template< typename Real >
+bool
+StaticVector< 3, Real >::setup( const Config::ParameterContainer& parameters,
+                                const String& prefix )
 {
+   this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" );
+   this->data[ 1 ] = parameters.getParameter< double >( prefix + "1" );
+   this->data[ 2 ] = parameters.getParameter< double >( prefix + "2" );
+   return true;
 }
 
 template< typename Real >
@@ -164,6 +178,7 @@ bool StaticVector< 3, Real >::operator >= ( const StaticVector& v ) const
             this->data[ 1 ] >= v[ 1 ] &&
             this->data[ 2 ] >= v[ 2 ] );
 }
+
 template< typename Real >
    template< typename OtherReal >
 __cuda_callable__
@@ -182,11 +197,30 @@ __cuda_callable__
 StaticVector< 3, Real >
 StaticVector< 3, Real >::abs() const
 {
-   return StaticVector< 3, Real >( ::abs( this->data[ 0 ] ),
-                                      ::abs( this->data[ 1 ] ),
-                                      ::abs( this->data[ 2 ] ) );
+   return StaticVector< 3, Real >( TNL::abs( this->data[ 0 ] ),
+                                   TNL::abs( this->data[ 1 ] ),
+                                   TNL::abs( this->data[ 2 ] ) );
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+StaticVector< 3, Real >::lpNorm( const Real& p ) const
+{
+   if( p == 1.0 )
+      return TNL::abs( this->data[ 0 ] ) + 
+             TNL::abs( this->data[ 1 ] ) + 
+             TNL::abs( this->data[ 2 ] );
+   if( p == 2.0 )
+      return TNL::sqrt( this->data[ 0 ] * this->data[ 0 ] + 
+                        this->data[ 1 ] * this->data[ 1 ] +
+                        this->data[ 2 ] * this->data[ 2 ] );
+   return TNL::pow( TNL::pow( TNL::abs( this->data[ 0 ] ), p ) +
+                    TNL::pow( TNL::abs( this->data[ 1 ] ), p ) +
+                    TNL::pow( TNL::abs( this->data[ 2 ] ), p ), 1.0 / p ); 
+}
+
+
 
 #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION
 
diff --git a/src/TNL/Containers/StaticVector_impl.h b/src/TNL/Containers/StaticVector_impl.h
index 251c1e7369e6c20e141ef3fa2fb675d217be4654..45e680a098f36aeeed127295f210dcad5d629d28 100644
--- a/src/TNL/Containers/StaticVector_impl.h
+++ b/src/TNL/Containers/StaticVector_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Containers/StaticVector.h>
+
 namespace TNL {
 namespace Containers {   
 
@@ -20,26 +22,38 @@ StaticVector< Size, Real >::StaticVector()
 }
 
 template< int Size, typename Real >
+   template< typename _unused >
 __cuda_callable__
 StaticVector< Size, Real >::StaticVector( const Real v[ Size ] )
-: Containers::StaticArray< Size, Real >( v )
+: StaticArray< Size, Real >( v )
 {
 }
 
 template< int Size, typename Real >
 __cuda_callable__
 StaticVector< Size, Real >::StaticVector( const Real& v )
-: Containers::StaticArray< Size, Real >( v )
+: StaticArray< Size, Real >( v )
 {
 }
 
 template< int Size, typename Real >
 __cuda_callable__
 StaticVector< Size, Real >::StaticVector( const StaticVector< Size, Real >& v )
-: Containers::StaticArray< Size, Real >( v )
+: StaticArray< Size, Real >( v )
 {
 }
 
+template< int Size, typename Real >
+bool
+StaticVector< Size, Real >::setup( const Config::ParameterContainer& parameters,
+                                   const String& prefix )
+{
+   for( int i = 0; i < Size; i++ )
+      if( ! parameters.template getParameter< double >( prefix + String( i ), this->data[ i ] ) )
+         return false;
+   return true;
+}
+
 template< int Size, typename Real >
 String StaticVector< Size, Real >::getType()
 {
@@ -180,9 +194,34 @@ StaticVector< Size, Real >::abs() const
    return v;
 }
 
-
 template< int Size, typename Real >
-StaticVector< Size, Real > operator * ( const Real& c, const StaticVector< Size, Real >& u )
+__cuda_callable__
+Real
+StaticVector< Size, Real >::lpNorm( const Real& p ) const
+{
+   if( p == 1.0 )
+   {
+      Real aux = TNL::abs( this->data[ 0 ] );
+      for( int i = 1; i < Size; i++ )
+         aux += TNL::abs( this->data[ i ] );
+      return aux;
+   }
+   if( p == 2.0 )
+   {
+      Real aux = this->data[ 0 ] * this->data[ 0 ];
+      for( int i = 1; i < Size; i++ )
+         aux += this->data[ i ] * this->data[ i ];
+      return TNL::sqrt( aux );
+   }
+   Real aux = TNL::pow( TNL::abs( this->data[ 0 ] ), p );
+   for( int i = 1; i < Size; i++ )
+      aux += TNL::pow( TNL::abs( this->data[ i ] ), p );
+   return TNL::pow( aux, 1.0 / p );
+}
+
+template< int Size, typename Real, typename Scalar >
+__cuda_callable__
+StaticVector< Size, Real > operator * ( const Scalar& c, const StaticVector< Size, Real >& u )
 {
    return u * c;
 }
diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h
index 0a73dd6988a0ecf687f0a2d6194d329b0cf7b7b9..01a6a3682f5d7779ec227732e0d682c5ef454109 100644
--- a/src/TNL/Containers/Vector.h
+++ b/src/TNL/Containers/Vector.h
@@ -11,22 +11,13 @@
 #pragma once
 
 #include <TNL/Containers/Array.h>
-#include <TNL/Functions/Domain.h>
 
 namespace TNL {
-
-namespace Devices
-{ 
-   class Host;
-}
-
 namespace Containers {   
 
-
-
 template< typename Real = double,
-           typename Device = Devices::Host,
-           typename Index = int >
+          typename Device = Devices::Host,
+          typename Index = int >
 class Vector : public Containers::Array< Real, Device, Index >
 {
    public:
diff --git a/src/TNL/Containers/Vector_impl.h b/src/TNL/Containers/Vector_impl.h
index b602d003204f3de8417c323f90bfe50ac71b06fc..b5a233faa6be107c2f7f776b7a66f58c998eaeae 100644
--- a/src/TNL/Containers/Vector_impl.h
+++ b/src/TNL/Containers/Vector_impl.h
@@ -10,7 +10,8 @@
 
 #pragma once 
 
-#include <TNL/Containers/VectorOperations.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/Algorithms/VectorOperations.h>
 
 namespace TNL {
 namespace Containers {   
@@ -18,15 +19,16 @@ namespace Containers {
 template< typename Real,
           typename Device,
           typename Index >
-Vector< Real, Device, Index >::Vector()
+Vector< Real, Device, Index >::
+Vector()
 {
-
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-Vector< Real, Device, Index >::Vector( const Index size )
+Vector< Real, Device, Index >::
+Vector( const Index size )
 {
    this->setSize( size );
 }
@@ -35,18 +37,22 @@ Vector< Real, Device, Index >::Vector( const Index size )
 template< typename Real,
           typename Device,
           typename Index >
-String Vector< Real, Device, Index >::getType()
+String
+Vector< Real, Device, Index >::
+getType()
 {
    return String( "Containers::Vector< " ) +
-                    TNL::getType< Real >() + ", " +
-                     Device::getDeviceType() + ", " +
-                    TNL::getType< Index >() + " >";
+                  TNL::getType< Real >() + ", " +
+                  Device::getDeviceType() + ", " +
+                  TNL::getType< Index >() + " >";
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-String Vector< Real, Device, Index >::getTypeVirtual() const
+String
+Vector< Real, Device, Index >::
+getTypeVirtual() const
 {
    return this->getType();
 };
@@ -54,7 +60,9 @@ String Vector< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-String Vector< Real, Device, Index >::getSerializationType()
+String
+Vector< Real, Device, Index >::
+getSerializationType()
 {
    return HostType::getType();
 };
@@ -62,7 +70,9 @@ String Vector< Real, Device, Index >::getSerializationType()
 template< typename Real,
           typename Device,
           typename Index >
-String Vector< Real, Device, Index >::getSerializationTypeVirtual() const
+String
+Vector< Real, Device, Index >::
+getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
@@ -70,27 +80,32 @@ String Vector< Real, Device, Index >::getSerializationTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-void Vector< Real, Device, Index >::addElement( const IndexType i,
-                                                   const RealType& value )
+void
+Vector< Real, Device, Index >::
+addElement( const IndexType i,
+            const RealType& value )
 {
-   VectorOperations< Device >::addElement( *this, i, value );
+   Algorithms::VectorOperations< Device >::addElement( *this, i, value );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void Vector< Real, Device, Index >::addElement( const IndexType i,
-                                                   const RealType& value,
-                                                   const RealType& thisElementMultiplicator )
+void
+Vector< Real, Device, Index >::
+addElement( const IndexType i,
+            const RealType& value,
+            const RealType& thisElementMultiplicator )
 {
-   VectorOperations< Device >::addElement( *this, i, value, thisElementMultiplicator );
+   Algorithms::VectorOperations< Device >::addElement( *this, i, value, thisElementMultiplicator );
 }
 
 template< typename Real,
-           typename Device,
-           typename Index >
+          typename Device,
+          typename Index >
 Vector< Real, Device, Index >&
-   Vector< Real, Device, Index >::operator = ( const Vector< Real, Device, Index >& vector )
+Vector< Real, Device, Index >::
+operator = ( const Vector< Real, Device, Index >& vector )
 {
    Containers::Array< Real, Device, Index >::operator = ( vector );
    return ( *this );
@@ -101,7 +116,8 @@ template< typename Real,
            typename Index >
    template< typename VectorT >
 Vector< Real, Device, Index >&
-   Vector< Real, Device, Index >::operator = ( const VectorT& vector )
+Vector< Real, Device, Index >::
+operator = ( const VectorT& vector )
 {
    Containers::Array< Real, Device, Index >::operator = ( vector );
    return ( *this );
@@ -111,7 +127,9 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename VectorT >
-bool Vector< Real, Device, Index >::operator == ( const VectorT& vector ) const
+bool
+Vector< Real, Device, Index >::
+operator == ( const VectorT& vector ) const
 {
    return Containers::Array< Real, Device, Index >::operator == ( vector );
 }
@@ -120,7 +138,9 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename VectorT >
-bool Vector< Real, Device, Index >::operator != ( const VectorT& vector ) const
+bool
+Vector< Real, Device, Index >::
+operator != ( const VectorT& vector ) const
 {
    return Containers::Array< Real, Device, Index >::operator != ( vector );
 }
@@ -129,7 +149,9 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename VectorT >
-Vector< Real, Device, Index >& Vector< Real, Device, Index >::operator -= ( const VectorT& vector )
+Vector< Real, Device, Index >&
+Vector< Real, Device, Index >::
+operator -= ( const VectorT& vector )
 {
    this->addVector( vector, -1.0 );
    return *this;
@@ -139,7 +161,9 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename VectorT >
-Vector< Real, Device, Index >& Vector< Real, Device, Index >::operator += ( const VectorT& vector )
+Vector< Real, Device, Index >&
+Vector< Real, Device, Index >::
+operator += ( const VectorT& vector )
 {
    this->addVector( vector );
    return *this;
@@ -148,18 +172,22 @@ Vector< Real, Device, Index >& Vector< Real, Device, Index >::operator += ( cons
 template< typename Real,
           typename Device,
           typename Index >
-Vector< Real, Device, Index >& Vector< Real, Device, Index >::operator *= ( const RealType& c )
+Vector< Real, Device, Index >&
+Vector< Real, Device, Index >::
+operator *= ( const RealType& c )
 {
-   VectorOperations< Device >::vectorScalarMultiplication( *this, c );
+   Algorithms::VectorOperations< Device >::vectorScalarMultiplication( *this, c );
    return *this;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-Vector< Real, Device, Index >& Vector< Real, Device, Index >::operator /= ( const RealType& c )
+Vector< Real, Device, Index >&
+Vector< Real, Device, Index >::
+operator /= ( const RealType& c )
 {
-   VectorOperations< Device >::vectorScalarMultiplication( *this, 1.0 / c );
+   Algorithms::VectorOperations< Device >::vectorScalarMultiplication( *this, 1.0 / c );
    return *this;
 }
 
@@ -169,7 +197,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::max() const
 {
-   return VectorOperations< Device >::getVectorMax( *this );
+   return Algorithms::VectorOperations< Device >::getVectorMax( *this );
 }
 
 template< typename Real,
@@ -177,7 +205,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::min() const
 {
-   return VectorOperations< Device >::getVectorMin( *this );
+   return Algorithms::VectorOperations< Device >::getVectorMin( *this );
 }
 
 
@@ -186,7 +214,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::absMax() const
 {
-   return VectorOperations< Device >::getVectorAbsMax( *this );
+   return Algorithms::VectorOperations< Device >::getVectorAbsMax( *this );
 }
 
 template< typename Real,
@@ -194,7 +222,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::absMin() const
 {
-   return VectorOperations< Device >::getVectorAbsMin( *this );
+   return Algorithms::VectorOperations< Device >::getVectorAbsMin( *this );
 }
 
 template< typename Real,
@@ -202,7 +230,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::lpNorm( const Real& p ) const
 {
-   return VectorOperations< Device >::getVectorLpNorm( *this, p );
+   return Algorithms::VectorOperations< Device >::getVectorLpNorm( *this, p );
 }
 
 
@@ -211,7 +239,7 @@ template< typename Real,
           typename Index >
 Real Vector< Real, Device, Index >::sum() const
 {
-   return VectorOperations< Device >::getVectorSum( *this );
+   return Algorithms::VectorOperations< Device >::getVectorSum( *this );
 }
 
 
@@ -221,7 +249,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceMax( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceMax( *this, v );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceMax( *this, v );
 }
 
 
@@ -231,7 +259,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceMin( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceMin( *this, v );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceMin( *this, v );
 }
 
 
@@ -241,7 +269,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceAbsMax( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceAbsMax( *this, v );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceAbsMax( *this, v );
 }
 
 template< typename Real,
@@ -250,7 +278,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceAbsMin( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceAbsMin( *this, v );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceAbsMin( *this, v );
 }
 
 template< typename Real,
@@ -259,7 +287,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceLpNorm( const VectorT& v, const Real& p ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceLpNorm( *this, v, p );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceLpNorm( *this, v, p );
 }
 
 
@@ -269,7 +297,7 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::differenceSum( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getVectorDifferenceSum( *this, v );
+   return Algorithms::VectorOperations< Device >::getVectorDifferenceSum( *this, v );
 }
 
 
@@ -278,7 +306,7 @@ template< typename Real,
           typename Index >
 void Vector< Real, Device, Index >::scalarMultiplication( const Real& alpha )
 {
-   VectorOperations< Device >::vectorScalarMultiplication( *this, alpha );
+   Algorithms::VectorOperations< Device >::vectorScalarMultiplication( *this, alpha );
 }
 
 
@@ -288,18 +316,20 @@ template< typename Real,
 template< typename VectorT >
 Real Vector< Real, Device, Index >::scalarProduct( const VectorT& v ) const
 {
-   return VectorOperations< Device >::getScalarProduct( *this, v );
+   return Algorithms::VectorOperations< Device >::getScalarProduct( *this, v );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 template< typename VectorT >
-void Vector< Real, Device, Index >::addVector( const VectorT& x,
-                                                    const Real& multiplicator,
-                                                    const Real& thisMultiplicator )
+void
+Vector< Real, Device, Index >::
+addVector( const VectorT& x,
+           const Real& multiplicator,
+           const Real& thisMultiplicator )
 {
-   VectorOperations< Device >::addVector( *this, x, multiplicator, thisMultiplicator );
+   Algorithms::VectorOperations< Device >::addVector( *this, x, multiplicator, thisMultiplicator );
 }
 
 template< typename Real,
@@ -314,7 +344,7 @@ addVectors( const VectorT& v1,
             const Real& multiplicator2,
             const Real& thisMultiplicator )
 {
-   VectorOperations< Device >::addVectors( *this, v1, multiplicator1, v2, multiplicator2, thisMultiplicator );
+   Algorithms::VectorOperations< Device >::addVectors( *this, v1, multiplicator1, v2, multiplicator2, thisMultiplicator );
 }
 
 template< typename Real,
@@ -322,16 +352,18 @@ template< typename Real,
           typename Index >
 void Vector< Real, Device, Index >::computePrefixSum()
 {
-   VectorOperations< Device >::computePrefixSum( *this, 0, this->getSize() );
+   Algorithms::VectorOperations< Device >::computePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void Vector< Real, Device, Index >::computePrefixSum( const IndexType begin,
-                                                           const IndexType end )
+void
+Vector< Real, Device, Index >::
+computePrefixSum( const IndexType begin,
+                  const IndexType end )
 {
-   VectorOperations< Device >::computePrefixSum( *this, begin, end );
+   Algorithms::VectorOperations< Device >::computePrefixSum( *this, begin, end );
 }
 
 template< typename Real,
@@ -339,16 +371,18 @@ template< typename Real,
           typename Index >
 void Vector< Real, Device, Index >::computeExclusivePrefixSum()
 {
-   VectorOperations< Device >::computeExclusivePrefixSum( *this, 0, this->getSize() );
+   Algorithms::VectorOperations< Device >::computeExclusivePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void Vector< Real, Device, Index >::computeExclusivePrefixSum( const IndexType begin,
-                                                                    const IndexType end )
+void
+Vector< Real, Device, Index >::
+computeExclusivePrefixSum( const IndexType begin,
+                           const IndexType end )
 {
-   VectorOperations< Device >::computeExclusivePrefixSum( *this, begin, end );
+   Algorithms::VectorOperations< Device >::computeExclusivePrefixSum( *this, begin, end );
 }
 
 
diff --git a/src/TNL/CudaStreamPool.h b/src/TNL/CudaStreamPool.h
index 780d95e4de983c363dfc042f424d57e895700a18..aa0a3e5d1e2ddee0d4416040ae9815f5242955f6 100644
--- a/src/TNL/CudaStreamPool.h
+++ b/src/TNL/CudaStreamPool.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          UniquePointer.h  -  description
+                             -------------------
+    begin                : Oct 14, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <stdlib.h>
diff --git a/src/TNL/Curve.h b/src/TNL/Curve.h
index ace8d622be4afa36cbde901b3d8847a358294f1f..f6f0408db82016340bbce152de4fdeb3111ab4f8 100644
--- a/src/TNL/Curve.h
+++ b/src/TNL/Curve.h
@@ -13,7 +13,7 @@
 #include <iomanip>
 #include <fstream>
 #include <cstring>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/Object.h>
 #include <TNL/Math.h>
 #include <TNL/Containers/StaticVector.h>
@@ -22,7 +22,8 @@
 namespace TNL {
 
 //! Basic structure for curves
-template< class T > class CurveElement
+template< class T >
+class CurveElement
 {
    public:
    CurveElement() {};
@@ -34,36 +35,20 @@ template< class T > class CurveElement
  
    bool save( File& file ) const
    {
-#ifdef HAVE_NOT_CXX11
-      if( ! file. write< const T, Devices::Host >( &position ) )
-         return false;
-      if( ! file. write< const bool, Devices::Host >( &separator ) )
-         return false;
-      return true;
-#else
       if( ! file. write( &position ) )
          return false;
       if( ! file. write( &separator ) )
          return false;
       return true;
-#endif
    };
  
    bool load( File& file )
    {
-#ifdef HAVE_NOT_CXX11
-      if( ! file. read< T, Devices::Host >( &position ) )
-         return false;
-      if( ! file. read< bool, Devices::Host >( &separator ) )
-         return false;
-      return true;
-#else
       if( ! file. read( &position ) )
          return false;
       if( ! file. read( &separator ) )
          return false;
       return true;
-#endif
    };
  
    T position;
@@ -71,7 +56,10 @@ template< class T > class CurveElement
    bool separator;
 };
 
-template< class T > class Curve : public Object, public List< CurveElement< T > >
+template< class T >
+class Curve
+ : public Object,
+   public Containers::List< CurveElement< T > >
 {
    public:
    //! Basic contructor
@@ -94,20 +82,20 @@ template< class T > class Curve : public Object, public List< CurveElement< T >
    //! Append new point
    void Append( const T& vec, bool separator = false )
    {
-      List< CurveElement< T > > :: Append( CurveElement< T >( vec, separator ) );
+      Containers::List< CurveElement< T > > :: Append( CurveElement< T >( vec, separator ) );
    };
 
    //! Erase the curve
    void Erase()
    {
-      List< CurveElement< T > >::reset();
+      Containers::List< CurveElement< T > >::reset();
    };
  
    //! Method for saving the object to a file as a binary data
    bool save( File& file ) const
    {
       if( ! Object :: save( file ) ) return false;
-      if( ! List< CurveElement< T > > :: DeepSave( file ) ) return false;
+      if( ! Containers::List< CurveElement< T > > :: DeepSave( file ) ) return false;
       return true;
    };
 
@@ -115,7 +103,7 @@ template< class T > class Curve : public Object, public List< CurveElement< T >
    bool load( File& file )
    {
       if( ! Object :: load( file ) ) return false;
-      if( ! List< CurveElement< T > > :: DeepLoad( file ) ) return false;
+      if( ! Containers::List< CurveElement< T > > :: DeepLoad( file ) ) return false;
       return true;
    };
 
@@ -178,7 +166,7 @@ template< class T > bool Write( const Curve< T >& curve,
    if( strncmp( format, "tnl",3 ) == 0 )
    {
       File file;
-      if( ! file. open( String( file_name ) + String( ".tnl" ), tnlWriteMode ) )
+      if( ! file. open( String( file_name ) + String( ".tnl" ), IOMode::write ) )
       {
          std::cerr << "I am not able to open the file " << file_name << " for drawing curve." << std::endl;
          return false;
@@ -214,7 +202,7 @@ template< class T > bool Read( Curve< T >& crv,
                                const char* input_file )
 {
    File file;
-   if( ! file. open( String( input_file ), tnlReadMode  ) )
+   if( ! file. open( String( input_file ), IOMode::read  ) )
    {
      std::cout << " unable to open file " << input_file << std::endl;
       return false;
diff --git a/src/TNL/Debugging/CMakeLists.txt b/src/TNL/Debugging/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d689cdaa12eef26c1feb3a061223a2d32271b58f
--- /dev/null
+++ b/src/TNL/Debugging/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET( headers
+         FPE.h
+         MemoryUsage.h
+         StackBacktrace.h
+)
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Debugging )
diff --git a/src/TNL/Debugging/FPE.h b/src/TNL/Debugging/FPE.h
new file mode 100644
index 0000000000000000000000000000000000000000..09011e8953205089db602357ad9840965dc95ede
--- /dev/null
+++ b/src/TNL/Debugging/FPE.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+                          MeshConfigBase.h  -  description
+                             -------------------
+    begin                : Nov 6, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <cfenv>
+#include <signal.h>
+
+#include <TNL/Debugging/StackBacktrace.h>
+
+namespace TNL {
+namespace Debugging {
+
+static void
+printStackBacktraceAndAbort( int sig = 0 )
+{
+   if( sig == SIGSEGV )
+      fprintf(stderr, "Invalid memory reference, printing backtrace and aborting...\n");
+   else if( sig == SIGFPE ) {
+      /*
+       * Unfortunately it is not possible to get the floating-point exception type
+       * from a signal handler. Otherwise, it would be done this way:
+       *
+       *    fprintf(stderr, "Floating-point exception");
+       *    if(fetestexcept(FE_DIVBYZERO))  fprintf(stderr, " FE_DIVBYZERO");
+       *    if(fetestexcept(FE_INEXACT))    fprintf(stderr, " FE_INEXACT");
+       *    if(fetestexcept(FE_INVALID))    fprintf(stderr, " FE_INVALID");
+       *    if(fetestexcept(FE_OVERFLOW))   fprintf(stderr, " FE_OVERFLOW");
+       *    if(fetestexcept(FE_UNDERFLOW))  fprintf(stderr, " FE_UNDERFLOW");
+       *    fprintf(stderr, " occurred, printing backtrace and aborting...\n");
+       */
+      fprintf(stderr, "Floating-point exception occurred, printing backtrace and aborting...\n");
+   }
+   else
+      fprintf( stderr, "Aborting due to signal %d...\n", sig );
+   printStackBacktrace();
+   abort();
+}
+
+/*
+ * Registers handler for SIGSEGV and SIGFPE signals and enables conversion of
+ * floating-point exceptions into SIGFPE. This is useful e.g. for tracing where
+ * NANs occurred. Example usage:
+ *
+ * int main()
+ * {
+ *    #ifndef NDEBUG
+ *       registerFloatingPointExceptionTracking()
+ *    #endif
+ *    [start some computation here...]
+ * }
+ */
+static void
+trackFloatingPointExceptions()
+{
+   signal( SIGSEGV, printStackBacktraceAndAbort );
+   signal( SIGFPE,  printStackBacktraceAndAbort );
+   feenableexcept( FE_ALL_EXCEPT & ~FE_INEXACT );
+}
+
+} // namespace Debugging
+} // namespace TNL
diff --git a/src/TNL/Debugging/MemoryUsage.h b/src/TNL/Debugging/MemoryUsage.h
new file mode 100644
index 0000000000000000000000000000000000000000..03ea3fe4d3db40f566ce82762521da1596e45dd5
--- /dev/null
+++ b/src/TNL/Debugging/MemoryUsage.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+                          MeshConfigBase.h  -  description
+                             -------------------
+    begin                : Nov 6, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <limits>
+
+namespace TNL {
+namespace Debugging {
+
+/*
+ * Prints memory usage of the current process into the specified stream.
+ *
+ * The information is obtained from /proc/self/status, which is assumed to be
+ * present on the system. The meaning of the printed values is following:
+ *  
+ *  - VmSize: Virtual memory size.
+ *  - VmRSS: Resident set size.
+ *  - VmHWM: Peak resident set size ("high water mark").
+ *
+ * See the proc(5) manual on Linux for details.
+ */
+static void
+printMemoryUsage( std::ostream& str = std::cerr )
+{
+   std::ifstream meminfo("/proc/self/status");
+   if( meminfo.fail() ) {
+      std::cerr << "error: unable to open /proc/self/status" << std::endl;
+      return;
+   }
+
+   unsigned vm = 0;
+   unsigned rss = 0;
+   unsigned hwm = 0;
+
+   std::string desc;
+   while( meminfo.good() ) {
+       // extract description (first column)
+       meminfo >> desc;
+
+       if( desc == "VmSize:" )
+           meminfo >> vm;
+       if( desc == "VmHWM:" )
+           meminfo >> hwm;
+       if( desc == "VmRSS:" )
+           meminfo >> rss;
+
+       // ignore the rest of irrelevant lines
+       meminfo.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
+   }
+
+   str << "Memory usage (MiB): "
+       << "VmSize = " << vm / 1024 << "MiB, "
+       << "VmRSS = " << rss / 1024 << "MiB, "
+       << "VmHWM = " << hwm / 1024 << "MiB, "
+       << std::endl;
+}
+
+} // namespace Debugging
+} // namespace TNL
diff --git a/src/TNL/Debugging/StackBacktrace.h b/src/TNL/Debugging/StackBacktrace.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee419922637899c7187e25d187abc6a427ebff68
--- /dev/null
+++ b/src/TNL/Debugging/StackBacktrace.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+                          MeshConfigBase.h  -  description
+                             -------------------
+    begin                : Nov 6, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <execinfo.h>
+#include <cxxabi.h>
+
+namespace TNL {
+namespace Debugging {
+
+#ifndef NDEBUG
+/*
+ * Print a demangled stack backtrace of the caller function to FILE* out.
+ *
+ * Reference: http://panthema.net/2008/0901-stacktrace-demangled/
+ *
+ * Note that the program must be linked with the -rdynamic flag, otherwise
+ * demangling will not work.
+ */
+static void
+printStackBacktrace( FILE *out = stderr, unsigned int max_frames = 63 )
+{
+   fprintf(out, "stack trace:\n");
+
+   // storage array for stack trace address data
+   void* addrlist[max_frames+1];
+
+   // retrieve current stack addresses
+   int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
+
+   if (addrlen == 0) {
+      fprintf(out, "  <empty, possibly corrupt>\n");
+      return;
+   }
+
+   // resolve addresses into strings containing "filename(function+address)",
+   // this array must be free()-ed
+   char** symbollist = backtrace_symbols(addrlist, addrlen);
+
+   // allocate string which will be filled with the demangled function name
+   size_t funcnamesize = 256;
+   char* funcname = (char*)malloc(funcnamesize);
+
+   // iterate over the returned symbol lines. skip the first, it is the
+   // address of this function.
+   for (int i = 1; i < addrlen; i++) {
+      char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
+
+      // find parentheses and +address offset surrounding the mangled name:
+      // ./module(function+0x15c) [0x8048a6d]
+      for (char *p = symbollist[i]; *p; ++p) {
+         if (*p == '(')
+            begin_name = p;
+         else if (*p == '+')
+            begin_offset = p;
+         else if (*p == ')' && begin_offset) {
+            end_offset = p;
+            break;
+         }
+      }
+
+      if (begin_name && begin_offset && end_offset && begin_name < begin_offset) {
+         *begin_name++ = '\0';
+         *begin_offset++ = '\0';
+         *end_offset = '\0';
+
+         // mangled name is now in [begin_name, begin_offset) and caller
+         // offset in [begin_offset, end_offset). now apply
+         // __cxa_demangle():
+
+         int status;
+         char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status);
+         if (status == 0) {
+            funcname = ret; // use possibly realloc()-ed string
+            fprintf(out, "  %d %s : %s+%s\n",
+               i, symbollist[i], funcname, begin_offset);
+         }
+         else {
+            // demangling failed. Output function name as a C function with no arguments.
+            fprintf(out, "  %d %s : %s()+%s\n",
+               i, symbollist[i], begin_name, begin_offset);
+         }
+      }
+      else {
+         // couldn't parse the line? print the whole line.
+         fprintf(out, "  %d %s\n", i, symbollist[i]);
+      }
+   }
+
+   free(funcname);
+   free(symbollist);
+}
+#endif
+
+} // namespace Debugging
+} // namespace TNL
+
+#ifdef NDEBUG
+#define PrintStackBacktrace
+#else
+#define PrintStackBacktrace TNL::Debugging::printStackBacktrace();
+#endif
diff --git a/src/TNL/DevicePointer.h b/src/TNL/DevicePointer.h
index beaed6e42ec47eac9626a53a0f365ae8e6d2f25d..956973529cbc39ad4e9bc42366ae118298b03ca2 100644
--- a/src/TNL/DevicePointer.h
+++ b/src/TNL/DevicePointer.h
@@ -1,20 +1,15 @@
-/***************************************************************************
- *                                                                         *
- *   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.                                   *
- *                                                                         *
- ***************************************************************************/
-
 /***************************************************************************
                           DevicePointer.h  -  description
                              -------------------
     begin                : Sep 1, 2016
-    copyright            : (C) 2016 by Tomas Oberhuber
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <TNL/Devices/Host.h>
@@ -23,6 +18,8 @@
 
 #include <cstring>
 
+#include "Devices/MIC.h"
+
 
 namespace TNL {
 
@@ -118,11 +115,18 @@ class DevicePointer< Object, Devices::Host > : public SmartPointer
          return *( this->pointer );
       }
 
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pointer;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pointer;
+      }
+
       template< typename Device = Devices::Host >
       __cuda_callable__
       const Object& getData() const
@@ -285,19 +289,26 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
          return *( this->pointer );
       }
 
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pd;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pd;
+      }
+
       template< typename Device = Devices::Host >
       __cuda_callable__
       const Object& getData() const
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pointer, );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
             return *( this->pointer );
          if( std::is_same< Device, Devices::Cuda >::value )
@@ -309,9 +320,9 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
       Object& modifyData()
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pointer, );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
          {
             this->pd->maybe_modified = true;
@@ -380,10 +391,10 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
 #ifdef HAVE_CUDA
          if( this->modified() )
          {
-            Assert( this->pointer, );
-            Assert( this->cuda_pointer, );
+            TNL_ASSERT( this->pointer, );
+            TNL_ASSERT( this->cuda_pointer, );
             cudaMemcpy( (void*) this->cuda_pointer, (void*) this->pointer, sizeof( ObjectType ), cudaMemcpyHostToDevice );
-            if( ! checkCudaDevice ) {
+            if( ! TNL_CHECK_CUDA_DEVICE ) {
                return false;
             }
             this->set_last_sync_state();
@@ -414,12 +425,8 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
       {
          this->pointer = &obj;
          this->pd = new PointerData();
-         if( ! this->pd )
-            return false;
          // pass to device
          this->cuda_pointer = Devices::Cuda::passToDevice( *this->pointer );
-         if( ! this->cuda_pointer )
-            return false;
          // set last-sync state
          this->set_last_sync_state();
          Devices::Cuda::insertSmartPointer( this );
@@ -428,16 +435,16 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
 
       void set_last_sync_state()
       {
-         Assert( this->pointer, );
-         Assert( this->pd, );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
          std::memcpy( (void*) &this->pd->data_image, (void*) this->pointer, sizeof( Object ) );
          this->pd->maybe_modified = false;
       }
 
       bool modified()
       {
-         Assert( this->pointer, );
-         Assert( this->pd, );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
          // optimization: skip bitwise comparison if we're sure that the data is the same
          if( ! this->pd->maybe_modified )
             return false;
@@ -467,4 +474,304 @@ class DevicePointer< Object, Devices::Cuda > : public SmartPointer
       Object* cuda_pointer;
 };
 
+/****
+ * Specialization for MIC
+ */
+
+#ifdef HAVE_MIC
+template< typename Object >
+class DevicePointer< Object, Devices::MIC > : public SmartPointer
+{
+   private:
+      // Convenient template alias for controlling the selection of copy- and
+      // move-constructors and assignment operators using SFINAE.
+      // The type Object_ is "enabled" iff Object_ and Object are not the same,
+      // but after removing const and volatile qualifiers they are the same.
+      template< typename Object_ >
+      using Enabler = std::enable_if< ! std::is_same< Object_, Object >::value &&
+                                      std::is_same< typename std::remove_cv< Object >::type, Object_ >::value >;
+
+      // friend class will be needed for templated assignment operators
+      template< typename Object_, typename Device_ >
+      friend class DevicePointer;
+
+   public:
+
+      typedef Object ObjectType;
+      typedef Devices::MIC DeviceType;
+      typedef DevicePointer< Object, Devices::MIC > ThisType;
+
+      explicit  DevicePointer( ObjectType& obj )
+      : pointer( nullptr ),
+        pd( nullptr ),
+        mic_pointer( nullptr )
+      {
+         this->allocate( obj );
+      }
+
+      // this is needed only to avoid the default compiler-generated constructor
+      DevicePointer( const ThisType& pointer )
+      : pointer( pointer.pointer ),
+        pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         this->pd->counter += 1;
+      }
+
+      // conditional constructor for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      DevicePointer( const DevicePointer< Object_, DeviceType >& pointer )
+      : pointer( pointer.pointer ),
+        pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         this->pd->counter += 1;
+      }
+
+      // this is needed only to avoid the default compiler-generated constructor
+      DevicePointer( ThisType&& pointer )
+      : pointer( pointer.pointer ),
+        pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         pointer.pointer = nullptr;
+         pointer.pd = nullptr;
+         pointer.mic_pointer = nullptr;
+      }
+
+      // conditional constructor for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      DevicePointer( DevicePointer< Object_, DeviceType >&& pointer )
+      : pointer( pointer.pointer ),
+        pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         pointer.pointer = nullptr;
+         pointer.pd = nullptr;
+         pointer.mic_pointer = nullptr;
+      }
+
+      const Object* operator->() const
+      {
+         return this->pointer;
+      }
+
+      Object* operator->()
+      {
+         this->pd->maybe_modified = true;
+         return this->pointer;
+      }
+
+      const Object& operator *() const
+      {
+         return *( this->pointer );
+      }
+
+      Object& operator *()
+      {
+         this->pd->maybe_modified = true;
+         return *( this->pointer );
+      }
+
+      operator bool()
+      {
+         return this->pd;
+      }
+
+      template< typename Device = Devices::Host >
+      __cuda_callable__
+      const Object& getData() const
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+            return *( this->pointer );
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );
+      }
+
+      template< typename Device = Devices::Host >
+      __cuda_callable__
+      Object& modifyData()
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+         {
+            this->pd->maybe_modified = true;
+            return *( this->pointer );
+         }
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );
+      }
+
+      // this is needed only to avoid the default compiler-generated operator
+      const ThisType& operator=( const ThisType& ptr )
+      {
+         this->free();
+         this->pointer = ptr.pointer;
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         this->pd->counter += 1;
+         return *this;
+      }
+
+      // conditional operator for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      const ThisType& operator=( const DevicePointer< Object_, DeviceType >& ptr )
+      {
+         this->free();
+         this->pointer = ptr.pointer;
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         this->pd->counter += 1;
+         return *this;
+      }
+
+      // this is needed only to avoid the default compiler-generated operator
+      const ThisType& operator=( ThisType&& ptr )
+      {
+         this->free();
+         this->pointer = ptr.pointer;
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         ptr.pointer = nullptr;
+         ptr.pd = nullptr;
+         ptr.mic_pointer = nullptr;
+         return *this;
+      }
+
+      // conditional operator for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      const ThisType& operator=( DevicePointer< Object_, DeviceType >&& ptr )
+      {
+         this->free();
+         this->pointer = ptr.pointer;
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         ptr.pointer = nullptr;
+         ptr.pd = nullptr;
+         ptr.mic_pointer = nullptr;
+         return *this;
+      }
+
+      bool synchronize()
+      {
+         if( ! this->pd )
+            return true;
+         if( this->modified() )
+         {
+            TNL_ASSERT( this->pointer, );
+            TNL_ASSERT( this->mic_pointer, );
+            Devices::MIC::CopyToMIC((void*) this->mic_pointer, (void*) this->pointer, sizeof( ObjectType ));
+            this->set_last_sync_state();
+            return true;
+         }
+         return true;
+
+      }
+
+      ~DevicePointer()
+      {
+         this->free();
+         Devices::MIC::removeSmartPointer( this );
+      }
+
+   protected:
+
+      struct PointerData
+      {
+         char data_image[ sizeof(Object) ];
+         int counter = 1;
+         bool maybe_modified = false;
+      };
+
+      bool allocate( ObjectType& obj )
+      {
+         this->pointer = &obj;
+         this->pd = new PointerData();
+         if( ! this->pd )
+            return false;
+         // pass to device
+         this->mic_pointer = (ObjectType*)Devices::MIC::AllocMIC(sizeof(ObjectType));
+         if( ! this->mic_pointer )
+            return false;
+         Devices::MIC::CopyToMIC((void*)this->mic_pointer,(void*)this->pointer,sizeof(ObjectType));
+                 
+         // set last-sync state
+         this->set_last_sync_state();
+         Devices::MIC::insertSmartPointer( this );
+         return true;
+      }
+
+      void set_last_sync_state()
+      {
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         std::memcpy( (void*) &this->pd->data_image, (void*) this->pointer, sizeof( Object ) );
+         this->pd->maybe_modified = false;
+      }
+
+      bool modified()
+      {
+         TNL_ASSERT( this->pointer, );
+         TNL_ASSERT( this->pd, );
+         // optimization: skip bitwise comparison if we're sure that the data is the same
+         if( ! this->pd->maybe_modified )
+            return false;
+         return std::memcmp( (void*) &this->pd->data_image, (void*) this->pointer, sizeof( Object ) ) != 0;
+      }
+
+      void free()
+      {
+         if( this->pd )
+         {
+            if( ! --this->pd->counter )
+            {
+               delete this->pd;
+               this->pd = nullptr;
+               if( this->mic_pointer )
+                  Devices::MIC::FreeMIC( (void*) this->mic_pointer );
+            }
+         }
+      }
+
+      Object* pointer;
+
+      PointerData* pd;
+
+      // mic_pointer can't be part of PointerData structure, since we would be
+      // unable to dereference this-pd on the device
+      Object* mic_pointer;
+};
+#endif
+
+
+#if  (!defined(NDEBUG)) && (!defined(HAVE_MIC)) 
+namespace Assert {
+
+template< typename Object, typename Device >
+struct Formatter< DevicePointer< Object, Device > >
+{
+   static std::string
+   printToString( const DevicePointer< Object, Device >& value )
+   {
+      ::std::stringstream ss;
+      ss << "(DevicePointer< " << Object::getType() << ", " << Device::getDeviceType()
+         << " > object at " << &value << ")";
+      return ss.str();
+   }
+};
+
+} // namespace Assert
+#endif
+
 } // namespace TNL
diff --git a/src/TNL/Devices/CMakeLists.txt b/src/TNL/Devices/CMakeLists.txt
old mode 100755
new mode 100644
index f09e2b47947ea21af93619167ea415f6b62491e6..7b4babe28e75b075edecad776b68cd18983aa0bb
--- a/src/TNL/Devices/CMakeLists.txt
+++ b/src/TNL/Devices/CMakeLists.txt
@@ -1,12 +1,15 @@
 set (headers Cuda.h
              Cuda_impl.h
+             CudaCallable.h
              CudaDeviceInfo.h
-             Host.h )
+             Host.h
+             MIC.h )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Devices )
 set( common_SOURCES
      ${CURRENT_DIR}/Cuda.cpp
-     ${CURRENT_DIR}/Host.cpp )
+     ${CURRENT_DIR}/Host.cpp 
+     ${CURRENT_DIR}/MIC.cpp )
 
 IF( BUILD_CUDA )
    set( tnl_devices_CUDA__SOURCES
diff --git a/src/TNL/Devices/Cuda.cpp b/src/TNL/Devices/Cuda.cpp
index ef868455784575e3304ac4ad2416e6b856f38ce5..2c8f85aeca4c1fc27a76c14115c7e29cda8c4251 100644
--- a/src/TNL/Devices/Cuda.cpp
+++ b/src/TNL/Devices/Cuda.cpp
@@ -19,17 +19,13 @@ namespace TNL {
 namespace Devices {
 
 SmartPointersRegister Cuda::smartPointersRegister;
+Timer Cuda::smartPointersSynchronizationTimer;
 
 String Cuda::getDeviceType()
 {
    return String( "Cuda" );
 }
 
-int Cuda::getGPUTransferBufferSize()
-{
-   return 1 << 20;
-}
-
 int Cuda::getNumberOfBlocks( const int threads,
                              const int blockSize )
 {
@@ -42,14 +38,10 @@ int Cuda::getNumberOfGrids( const int blocks,
    return roundUpDivision( blocks, gridSize );
 }
 
-/*size_t Cuda::getFreeMemory()
-{
-
-}*/
-
 void Cuda::configSetup( Config::ConfigDescription& config,
                         const String& prefix )
 {
+// FIXME: HAVE_CUDA is never defined in .cpp files
 #ifdef HAVE_CUDA
    config.addEntry< int >( prefix + "cuda-device", "Choose CUDA device to run the computation.", 0 );
 #else
@@ -60,13 +52,16 @@ void Cuda::configSetup( Config::ConfigDescription& config,
 bool Cuda::setup( const Config::ParameterContainer& parameters,
                   const String& prefix )
 {
+// FIXME: HAVE_CUDA is never defined in .cpp files
 #ifdef HAVE_CUDA
-   int cudaDevice = parameters.getParameter< int >( "cuda-device" );
+   int cudaDevice = parameters.getParameter< int >( prefix + "cuda-device" );
    if( cudaSetDevice( cudaDevice ) != cudaSuccess )
    {
       std::cerr << "I cannot activate CUDA device number " << cudaDevice << "." << std::endl;
       return false;
    }
+   smartPointersSynchronizationTimer.reset();
+   smartPointersSynchronizationTimer.stop();
 #endif
    return true;
 }
@@ -85,7 +80,10 @@ bool Cuda::synchronizeDevice( int deviceId )
 {
    if( deviceId < 0 )
       deviceId = Devices::CudaDeviceInfo::getActiveDevice();
-   return smartPointersRegister.synchronizeDevice( deviceId );
+   smartPointersSynchronizationTimer.start();
+   bool b = smartPointersRegister.synchronizeDevice( deviceId );
+   smartPointersSynchronizationTimer.stop();
+   return b;
 }
 
 } // namespace Devices
diff --git a/src/TNL/Devices/Cuda.cu b/src/TNL/Devices/Cuda.cu
index 3d4ad065ddfa472ef50ca79bd3cd6fe43e49ce1b..2605e6dca83290eb59db54618b7bf91ed1e59150 100644
--- a/src/TNL/Devices/Cuda.cu
+++ b/src/TNL/Devices/Cuda.cu
@@ -9,419 +9,111 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Exceptions/CudaRuntimeError.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Config/ParameterContainer.h>
 
 namespace TNL {
 namespace Devices {
 
-/*void Cuda::configSetup( tnlConfigDescription& config, const String& prefix )
+
+void Cuda::setupThreads( const dim3& blockSize,
+                         dim3& blocksCount,
+                         dim3& gridsCount,
+                         long long int xThreads,
+                         long long int yThreads,
+                         long long int zThreads )
 {
-#ifdef HAVE_CUDA
-   config.addEntry< int >( prefix + "cuda-device", "Choose CUDA device.", 0 );
-#else
-   config.addEntry< int >( prefix + "cuda-device", "Choose CUDA device (CUDA is not supported on this system).", 0 );
-#endif
+   blocksCount.x = max( 1, xThreads / blockSize.x + ( xThreads % blockSize.x != 0 ) );
+   blocksCount.y = max( 1, yThreads / blockSize.y + ( yThreads % blockSize.y != 0 ) );
+   blocksCount.z = max( 1, zThreads / blockSize.z + ( zThreads % blockSize.z != 0 ) );
+   
+   /****
+    * TODO: Fix the following:
+    * I do not known how to get max grid size in kernels :(
+    * 
+    * Also, this is very slow. */
+   /*int currentDevice( 0 );
+   cudaGetDevice( currentDevice );
+   cudaDeviceProp properties;
+   cudaGetDeviceProperties( &properties, currentDevice );
+   gridsCount.x = blocksCount.x / properties.maxGridSize[ 0 ] + ( blocksCount.x % properties.maxGridSize[ 0 ] != 0 );
+   gridsCount.y = blocksCount.y / properties.maxGridSize[ 1 ] + ( blocksCount.y % properties.maxGridSize[ 1 ] != 0 );
+   gridsCount.z = blocksCount.z / properties.maxGridSize[ 2 ] + ( blocksCount.z % properties.maxGridSize[ 2 ] != 0 );
+   */
+   gridsCount.x = blocksCount.x / getMaxGridSize() + ( blocksCount.x % getMaxGridSize() != 0 );
+   gridsCount.y = blocksCount.y / getMaxGridSize() + ( blocksCount.y % getMaxGridSize() != 0 );
+   gridsCount.z = blocksCount.z / getMaxGridSize() + ( blocksCount.z % getMaxGridSize() != 0 );
 }
- 
-bool Cuda::setup( const tnlParameterContainer& parameters,
-                    const String& prefix )
+
+void Cuda::setupGrid( const dim3& blocksCount,
+                      const dim3& gridsCount,
+                      const dim3& gridIdx,
+                      dim3& gridSize )
 {
-   int cudaDevice = parameters.getParameter< int >( prefix + "cuda-device" );
-#ifdef HAVE_CUDA
-    cudaSetDevice( cudaDevice );
-    checkCudaDevice;
-#endif
-   return true;
+   /* TODO: this is extremely slow!!!!
+   int currentDevice( 0 );
+   cudaGetDevice( &currentDevice );
+   cudaDeviceProp properties;
+   cudaGetDeviceProperties( &properties, currentDevice );*/
+ 
+   /****
+    * TODO: fix the following
+   if( gridIdx.x < gridsCount.x )
+      gridSize.x = properties.maxGridSize[ 0 ];
+   else
+      gridSize.x = blocksCount.x % properties.maxGridSize[ 0 ];
+   
+   if( gridIdx.y < gridsCount.y )
+      gridSize.y = properties.maxGridSize[ 1 ];
+   else
+      gridSize.y = blocksCount.y % properties.maxGridSize[ 1 ];
+
+   if( gridIdx.z < gridsCount.z )
+      gridSize.z = properties.maxGridSize[ 2 ];
+   else
+      gridSize.z = blocksCount.z % properties.maxGridSize[ 2 ];*/
+   
+   if( gridIdx.x < gridsCount.x - 1 )
+      gridSize.x = getMaxGridSize();
+   else
+      gridSize.x = blocksCount.x % getMaxGridSize();
+   
+   if( gridIdx.y < gridsCount.y - 1 )
+      gridSize.y = getMaxGridSize();
+   else
+      gridSize.y = blocksCount.y % getMaxGridSize();
+
+   if( gridIdx.z < gridsCount.z - 1 )
+      gridSize.z = getMaxGridSize();
+   else
+      gridSize.z = blocksCount.z % getMaxGridSize();
 }
-*/
 
-int Cuda::getDeviceId()
+void Cuda::printThreadsSetup( const dim3& blockSize,
+                              const dim3& blocksCount,
+                              const dim3& gridSize,
+                              const dim3& gridsCount,
+                              std::ostream& str )
 {
-   int id( 0 );
-#ifdef HAVE_CUDA
-   cudaGetDevice( &id );
-#endif
-   return id;
+   str << "Block size: " << blockSize << std::endl
+       << " Blocks count: " << blocksCount << std::endl
+       << " Grid size: " << gridSize << std::endl
+       << " Grids count: " << gridsCount << std::endl;
 }
 
+
 bool Cuda::checkDevice( const char* file_name, int line, cudaError error )
 {   
    if( error == cudaSuccess )
       return true;
-   std::cerr << "CUDA ERROR(" << error << ") at line " << line << " in " << file_name << ":" << std::endl;
-   std::cerr << cudaGetErrorString( error )  << std::endl;   
-   std::cerr << "Detailed description is: " << std::endl;
-   switch( error )
-   {
-      // 1
-      case cudaErrorMissingConfiguration:
-         std::cerr
-          << "The device function being invoked (usually via ::cudaLaunch()) was not " << std::endl
-          << "previously configured via the ::cudaConfigureCall() function. " << std::endl;
-       break;
-
-      // 2
-      case cudaErrorMemoryAllocation:
-         std::cerr
-          << "The API call failed because it was unable to allocate enough memory to " << std::endl
-          << "perform the requested operation. " << std::endl;
-       break;
-
-      // 3
-      case cudaErrorInitializationError:
-         std::cerr
-          << "The API call failed because the CUDA driver and runtime could not be " << std::endl
-          << "initialized. " << std::endl;
-       break;
- 
-      // 4
-      case cudaErrorLaunchFailure:
-         std::cerr
-          << "An exception occurred on the device while executing a kernel. Common " << std::endl
-          << "causes include dereferencing an invalid device pointer and accessing " << std::endl
-          << "out of bounds shared memory. The device cannot be used until " << std::endl
-          << "::cudaThreadExit() is called. All existing device memory allocations " << std::endl
-          << "are invalid and must be reconstructed if the program is to continue " << std::endl
-          << "using CUDA. " << std::endl;
-       break;
-
-      // 5
-      case cudaErrorPriorLaunchFailure:
-         std::cerr
-          << "This indicated that a previous kernel launch failed. This was previously " << std::endl
-          << "used for device emulation of kernel launches. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      // 6
-      case cudaErrorLaunchTimeout:
-         std::cerr
-          << "This indicates that the device kernel took too long to execute. This can " << std::endl
-          << "only occur if timeouts are enabled - see the device property " << std::endl
-          << "ref ::cudaDeviceProp::kernelExecTimeoutEnabled \"kernelExecTimeoutEnabled\" " << std::endl
-          << "for more information. The device cannot be used until ::cudaThreadExit() " << std::endl
-          << "is called. All existing device memory allocations are invalid and must be " << std::endl
-          << "reconstructed if the program is to continue using CUDA. " << std::endl;
-       break;
-
-      // 7
-      case cudaErrorLaunchOutOfResources:
-         std::cerr
-          << "This indicates that a launch did not occur because it did not have " << std::endl
-          << "appropriate resources. Although this error is similar to " << std::endl
-          << "::cudaErrorInvalidConfiguration, this error usually indicates that the " << std::endl
-          << "user has attempted to pass too many arguments to the device kernel, or the " << std::endl
-          << "kernel launch specifies too many threads for the kernel's register count. " << std::endl;
-       break;
-
-      // 8
-      case cudaErrorInvalidDeviceFunction:
-         std::cerr
-          << "The requested device function does not exist or is not compiled for the " << std::endl
-          << "proper device architecture. " << std::endl;
-       break;
- 
-      // 9
-      case cudaErrorInvalidConfiguration:
-         std::cerr
-          << "This indicates that a kernel launch is requesting resources that can " << std::endl
-          << "never be satisfied by the current device. Requesting more shared memory " << std::endl
-          << "per block than the device supports will trigger this error, as will " << std::endl
-          << "requesting too many threads or blocks. See ::cudaDeviceProp for more " << std::endl
-          << "device limitations. " << std::endl;
-       break;
-
-      // 10
-      case cudaErrorInvalidDevice:
-         std::cerr
-          << "This indicates that the device ordinal supplied by the user does not " << std::endl
-          << "correspond to a valid CUDA device. " << std::endl;
-       break;
-
-      // 11
-      case cudaErrorInvalidValue:
-         std::cerr
-          << "This indicates that one or more of the parameters passed to the API call " << std::endl
-          << "is not within an acceptable range of values. " << std::endl;
-       break;
-
-      // 12
-      case cudaErrorInvalidPitchValue:
-         std::cerr
-          << "This indicates that one or more of the pitch-related parameters passed " << std::endl
-          << "to the API call is not within the acceptable range for pitch. " << std::endl;
-       break;
-
-      // 13
-      case cudaErrorInvalidSymbol:
-         std::cerr
-          << "This indicates that the symbol name/identifier passed to the API call " << std::endl
-          << "is not a valid name or identifier. " << std::endl;
-       break;
-
-      // 14
-      case cudaErrorMapBufferObjectFailed:
-      std::cerr
-       << "This indicates that the buffer object could not be mapped. " << std::endl;
-       break;
-
-      // 15
-      case cudaErrorUnmapBufferObjectFailed:
-         std::cerr
-          << "This indicates that the buffer object could not be unmapped. " << std::endl;
-       break;
-
-      // 16
-      case cudaErrorInvalidHostPointer:
-         std::cerr
-          << "This indicates that at least one host pointer passed to the API call is " << std::endl
-          << "not a valid host pointer. " << std::endl;
-       break;
-
-      // 17
-      case cudaErrorInvalidDevicePointer:
-         std::cerr
-          << "This indicates that at least one device pointer passed to the API call is " << std::endl
-          << "not a valid device pointer. " << std::endl;
-       break;
-
-      case cudaErrorInvalidTexture:
-         std::cerr
-          << "This indicates that the texture passed to the API call is not a valid " << std::endl
-          << "texture. " << std::endl;
-       break;
-
-      case cudaErrorInvalidTextureBinding:
-         std::cerr
-          << "This indicates that the texture binding is not valid. This occurs if you " << std::endl
-          << "call ::cudaGetTextureAlignmentOffset() with an unbound texture. " << std::endl;
-       break;
-
-      case cudaErrorInvalidChannelDescriptor:
-         std::cerr
-          << "This indicates that the channel descriptor passed to the API call is not " << std::endl
-          << "valid. This occurs if the format is not one of the formats specified by " << std::endl
-          << "::cudaChannelFormatKind, or if one of the dimensions is invalid. " << std::endl;
-       break;
-
-      case cudaErrorInvalidMemcpyDirection:
-         std::cerr
-          << "This indicates that the direction of the memcpy passed to the API call is " << std::endl
-          << "not one of the types specified by ::cudaMemcpyKind. " << std::endl;
-       break;
-
-      case cudaErrorAddressOfConstant:
-         std::cerr
-          << "This indicated that the user has taken the address of a constant variable, " << std::endl
-          << "which was forbidden up until the CUDA 3.1 release. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Variables in constant " << std::endl
-          << "memory may now have their address taken by the runtime via " << std::endl
-          << "::cudaGetSymbolAddress(). " << std::endl;
-       break;
-
-      case cudaErrorTextureFetchFailed:
-         std::cerr
-          << "This indicated that a texture fetch was not able to be performed. " << std::endl
-          << "This was previously used for device emulation of texture operations. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      case cudaErrorTextureNotBound:
-         std::cerr
-          << "This indicated that a texture was not bound for access. " << std::endl
-          << "This was previously used for device emulation of texture operations. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      case cudaErrorSynchronizationError:
-         std::cerr
-          << "This indicated that a synchronization operation had failed. " << std::endl
-          << "This was previously used for some device emulation functions. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      case cudaErrorInvalidFilterSetting:
-         std::cerr
-          << "This indicates that a non-float texture was being accessed with linear " << std::endl
-          << "filtering. This is not supported by CUDA. " << std::endl;
-       break;
-
-      case cudaErrorInvalidNormSetting:
-         std::cerr
-          << "This indicates that an attempt was made to read a non-float texture as a " << std::endl
-          << "normalized float. This is not supported by CUDA. " << std::endl;
-       break;
-
-      case cudaErrorMixedDeviceExecution:
-         std::cerr
-          << "Mixing of device and device emulation code was not allowed. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      case cudaErrorCudartUnloading:
-         std::cerr
-          << "This indicated an issue with calling API functions during the unload " << std::endl
-          << "process of the CUDA runtime in prior releases. " << std::endl
-          << "This error return is deprecated as of CUDA 3.2. " << std::endl;
-       break;
-
-      case cudaErrorUnknown:
-         std::cerr
-          << "This indicates that an unknown internal error has occurred. " << std::endl;
-       break;
-
-      case cudaErrorNotYetImplemented:
-         std::cerr
-          << "This indicates that the API call is not yet implemented. Production " << std::endl
-          << "releases of CUDA will never return this error. " << std::endl;
-       break;
-
-      case cudaErrorMemoryValueTooLarge:
-         std::cerr
-          << "This indicated that an emulated device pointer exceeded the 32-bit address " << std::endl
-          << "range. " << std::endl
-          << "This error return is deprecated as of CUDA 3.1. Device emulation mode was " << std::endl
-          << "removed with the CUDA 3.1 release. " << std::endl;
-       break;
-
-      case cudaErrorInvalidResourceHandle:
-         std::cerr
-          << "This indicates that a resource handle passed to the API call was not " << std::endl
-          << "valid. Resource handles are opaque types like ::cudaStream_t and " << std::endl
-          << "::cudaEvent_t. " << std::endl;
-       break;
-
-      case cudaErrorNotReady:
-         std::cerr
-          << "This indicates that asynchronous operations issued previously have not " << std::endl
-          << "completed yet. This result is not actually an error, but must be indicated " << std::endl
-          << "differently than ::cudaSuccess (which indicates completion). Calls that " << std::endl
-          << "may return this value include ::cudaEventQuery() and ::cudaStreamQuery(). " << std::endl;
-       break;
-
-      case cudaErrorInsufficientDriver:
-         std::cerr
-          << "This indicates that the installed NVIDIA CUDA driver is older than the " << std::endl
-          << "CUDA runtime library. This is not a supported configuration. Users should " << std::endl
-          << "install an updated NVIDIA display driver to allow the application to run. " << std::endl;
-       break;
-
-      case cudaErrorSetOnActiveProcess:
-         std::cerr
-          << "This indicates that the user has called ::cudaSetDevice(), " << std::endl
-          << "::cudaSetValidDevices(), ::cudaSetDeviceFlags(), " << std::endl
-          << "::cudaD3D9SetDirect3DDevice(), ::cudaD3D10SetDirect3DDevice, " << std::endl
-          << "::cudaD3D11SetDirect3DDevice(), * or ::cudaVDPAUSetVDPAUDevice() after " << std::endl
-          << "initializing the CUDA runtime by calling non-device management operations " << std::endl
-          << "(allocating memory and launching kernels are examples of non-device " << std::endl
-          << "management operations). This error can also be returned if using " << std::endl
-          << "runtime/driver interoperability and there is an existing ::CUcontext " << std::endl
-          << "active on the host thread. " << std::endl;
-       break;
-
-      case cudaErrorInvalidSurface:
-         std::cerr
-          << "This indicates that the surface passed to the API call is not a valid " << std::endl
-          << "surface. " << std::endl;
-       break;
-
-      case cudaErrorNoDevice:
-      std::cerr
-       << "This indicates that no CUDA-capable devices were detected by the installed " << std::endl
-       << "CUDA driver. " << std::endl;
-       break;
-
-      case cudaErrorECCUncorrectable:
-      std::cerr
-       << "This indicates that an uncorrectable ECC error was detected during " << std::endl
-       << "execution. " << std::endl;
-       break;
-
-      case cudaErrorSharedObjectSymbolNotFound:
-      std::cerr
-       << "This indicates that a link to a shared object failed to resolve. " << std::endl;
-       break;
-
-      case cudaErrorSharedObjectInitFailed:
-      std::cerr
-       << "This indicates that initialization of a shared object failed. " << std::endl;
-       break;
-
-      case cudaErrorUnsupportedLimit:
-      std::cerr
-       << "This indicates that the ::cudaLimit passed to the API call is not " << std::endl
-       << "supported by the active device. " << std::endl;
-       break;
-
-      case cudaErrorDuplicateVariableName:
-      std::cerr
-       << "This indicates that multiple global or constant variables (across separate " << std::endl
-       << "CUDA source files in the application) share the same string name. " << std::endl;
-       break;
-
-      case cudaErrorDuplicateTextureName:
-      std::cerr
-       << "This indicates that multiple textures (across separate CUDA source " << std::endl
-       << "files in the application) share the same string name. " << std::endl;
-       break;
-
-      case cudaErrorDuplicateSurfaceName:
-      std::cerr
-       << "This indicates that multiple surfaces (across separate CUDA source " << std::endl
-       << "files in the application) share the same string name. " << std::endl;
-       break;
-
-      case cudaErrorDevicesUnavailable:
-      std::cerr
-       << "This indicates that all CUDA devices are busy or unavailable at the current " << std::endl
-       << "time. Devices are often busy/unavailable due to use of " << std::endl
-       << "::cudaComputeModeExclusive or ::cudaComputeModeProhibited. They can also " << std::endl
-       << "be unavailable due to memory constraints on a device that already has " << std::endl
-       << "active CUDA work being performed. " << std::endl;
-       break;
-
-      case cudaErrorInvalidKernelImage:
-      std::cerr
-       << "This indicates that the device kernel image is invalid. " << std::endl;
-       break;
-
-      case cudaErrorNoKernelImageForDevice:
-      std::cerr
-       << "This indicates that there is no kernel image available that is suitable " << std::endl
-       << "for the device. This can occur when a user specifies code generation " << std::endl
-       << "options for a particular CUDA source file that do not include the " << std::endl
-       << "corresponding device configuration. " << std::endl;
-       break;
-
-      case cudaErrorIncompatibleDriverContext:
-      std::cerr
-       << "This indicates that the current context is not compatible with this " << std::endl
-       << "version of the CUDA Runtime. This can only occur if you are using CUDA " << std::endl
-       << "Runtime/Driver interoperability and have created an existing Driver " << std::endl
-       << "context using an older API. Please see \ref CUDART_DRIVER " << std::endl
-       << "\"Interactions with the CUDA Driver API\" for more information. " << std::endl;
-       break;
-
-      case cudaErrorStartupFailure:
-      std::cerr
-       << "This indicates an internal startup failure in the CUDA runtime. " << std::endl;
-       break;
-
-      case cudaErrorApiFailureBase:
-      std::cerr
-       << "Any unhandled CUDA driver error is added to this value and returned via " << std::endl
-       << "the runtime. Production releases of CUDA should not return such errors. " << std::endl;
-       break;
+   throw Exceptions::CudaRuntimeError( error, file_name, line );
+}
 
-   }
-   throw EXIT_FAILURE;
-   return false;
+std::ostream& operator << ( std::ostream& str, const dim3& d )
+{
+   str << "( " << d.x << ", " << d.y << ", " << d.z << " )";
+   return str;
 }
 
 } // namespace Devices
diff --git a/src/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h
index 301b0091634e412522a52539563b2a8c0e6b122c..805a9c8a35845d2a48a583ecd28fc9559194e676 100644
--- a/src/TNL/Devices/Cuda.h
+++ b/src/TNL/Devices/Cuda.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          Devices::Cuda.h  -  description
+                          Cuda.h  -  description
                              -------------------
     begin                : Nov 7, 2012
     copyright            : (C) 2012 by Tomas Oberhuber
@@ -15,6 +15,8 @@
 #include <TNL/String.h>
 #include <TNL/Assert.h>
 #include <TNL/SmartPointersRegister.h>
+#include <TNL/Timer.h>
+#include <TNL/Devices/CudaCallable.h>
 
 namespace TNL {
 
@@ -25,43 +27,83 @@ namespace Config {
 
 namespace Devices {
 
-#ifdef HAVE_CUDA
-#define __cuda_callable__ __device__ __host__
-#else
-#define __cuda_callable__
-#endif
-
-
 class Cuda
 {
    public:
 
    static String getDeviceType();
 
-   __cuda_callable__ static inline int getMaxGridSize();
+   __cuda_callable__ static inline constexpr int getMaxGridSize();
+
+   __cuda_callable__ static inline constexpr int getMaxBlockSize();
 
-   __cuda_callable__ static inline int getMaxBlockSize();
+   __cuda_callable__ static inline constexpr int getWarpSize();
 
-   __cuda_callable__ static inline int getWarpSize();
+   __cuda_callable__ static inline constexpr int getNumberOfSharedMemoryBanks();
+
+   static inline constexpr int getGPUTransferBufferSize();
 
 #ifdef HAVE_CUDA
-   static int getDeviceId();
-   
-   template< typename Index >
-   __device__ static Index getGlobalThreadIdx( const Index gridIdx = 0 );
-#endif
+   /***
+    * This function is obsolete and should be replaced by the following functions.
+    */
+   __device__ static inline int
+   getGlobalThreadIdx( const int gridIdx = 0,
+                       const int gridSize = getMaxGridSize() );   
+
+   __device__ static inline int
+   getGlobalThreadIdx_x( const dim3& gridIdx );
 
-   __cuda_callable__ static inline int getNumberOfSharedMemoryBanks();
+   __device__ static inline int
+   getGlobalThreadIdx_y( const dim3& gridIdx );
 
-   static int getGPUTransferBufferSize();
+   __device__ static inline int
+   getGlobalThreadIdx_z( const dim3& gridIdx );   
+#endif
 
+   /****
+    * This functions helps to count number of CUDA blocks depending on the 
+    * number of the CUDA threads and the block size.
+    * It is obsolete and it will be replaced by setupThreads.
+    */
    static int getNumberOfBlocks( const int threads,
                                  const int blockSize );
 
+   /****
+    * This functions helps to count number of CUDA grids depending on the 
+    * number of the CUDA blocks and maximum grid size.
+    * It is obsolete and it will be replaced by setupThreads.
+    */
    static int getNumberOfGrids( const int blocks,
                                 const int gridSize = getMaxGridSize() );
-
-   static size_t getFreeMemory();
+   
+#ifdef HAVE_CUDA   
+   /*! This method sets up gridSize and computes number of grids depending
+    *  on total number of CUDA threads.
+    */
+   static void setupThreads( const dim3& blockSize,
+                             dim3& blocksCount,
+                             dim3& gridsCount,
+                             long long int xThreads,
+                             long long int yThreads = 0,
+                             long long int zThreads = 0 );
+   
+   /*! This method sets up grid size when one iterates over more grids.
+    * If gridIdx.? < gridsCount.? then the gridSize.? is set to maximum
+    * allowed by CUDA. Otherwise gridSize.? is set to the size of the grid
+    * in the last loop i.e. blocksCount.? % maxGridSize.?.
+    */
+   static void setupGrid( const dim3& blocksCount,
+                          const dim3& gridsCount,
+                          const dim3& gridIdx,
+                          dim3& gridSize );
+   
+   static void printThreadsSetup( const dim3& blockSize,
+                                  const dim3& blocksCount,
+                                  const dim3& gridSize,
+                                  const dim3& gridsCount,
+                                  std::ostream& str = std::cout );
+#endif   
 
    template< typename ObjectType >
    static ObjectType* passToDevice( const ObjectType& object );
@@ -82,17 +124,38 @@ class Cuda
 #ifdef HAVE_CUDA
    template< typename Index >
    static __device__ Index getInterleaving( const Index index );
+
+   /****
+    * Declaration of variables for dynamic shared memory is difficult in
+    * templated functions. For example, the following does not work for
+    * different types T:
+    *
+    *    template< typename T >
+    *    void foo()
+    *    {
+    *        extern __shared__ T shx[];
+    *    }
+    *
+    * This is because extern variables must be declared exactly once. In
+    * templated functions we need to have same variable name with different
+    * type, which causes the conflict. In CUDA samples they solve the problem
+    * using template specialization via classes, but using one base type and
+    * reinterpret_cast works too.
+    * See http://stackoverflow.com/a/19339004/4180822 for reference.
+    */
+   template< typename Element, size_t Alignment = sizeof( Element ) >
+   static __device__ Element* getSharedMemory();
 #endif
 
 #ifdef HAVE_CUDA
    /****
     * I do not know why, but it is more reliable to pass the error code instead
     * of calling cudaGetLastError() inside the method.
-    * We recommend to use macro 'checkCudaDevice' defined bellow.
+    * We recommend to use macro 'TNL_CHECK_CUDA_DEVICE' defined bellow.
     */
    static bool checkDevice( const char* file_name, int line, cudaError error );
 #else
-   static bool checkDevice() { return false;};
+   static bool checkDevice() { return false; };
 #endif
    
    static void configSetup( Config::ConfigDescription& config, const String& prefix = "" );
@@ -108,42 +171,21 @@ class Cuda
    // called to get the device ID.
    static bool synchronizeDevice( int deviceId = -1 );
    
+   static Timer smartPointersSynchronizationTimer;
+   
    protected:
    
    static SmartPointersRegister smartPointersRegister;
-
 };
 
 #ifdef HAVE_CUDA
-#define checkCudaDevice ::TNL::Devices::Cuda::checkDevice( __FILE__, __LINE__, cudaGetLastError() )
+#define TNL_CHECK_CUDA_DEVICE ::TNL::Devices::Cuda::checkDevice( __FILE__, __LINE__, cudaGetLastError() )
 #else
-#define checkCudaDevice ::TNL::Devices::Cuda::checkDevice()
+#define TNL_CHECK_CUDA_DEVICE ::TNL::Devices::Cuda::checkDevice()
 #endif
 
-#define CudaSupportMissingMessage \
-   std::cerr << "The CUDA support is missing in the source file " << __FILE__ << " at line " << __LINE__ << ". Please set WITH_CUDA=yes in the install script. " << std::endl;
-
-
-// TODO: This would be nice in Cuda but C++ standard does not allow it.
 #ifdef HAVE_CUDA
-   template< typename Element >
-   struct getSharedMemory
-   {
-       __device__ operator Element*();
-   };
-
-   template<>
-   struct getSharedMemory< double >
-   {
-       inline __device__ operator double*();
-   };
-
-   template<>
-   struct getSharedMemory< long int >
-   {
-       inline __device__ operator long int*();
-   };
-
+std::ostream& operator << ( std::ostream& str, const dim3& d );
 #endif
 
 } // namespace Devices
diff --git a/src/TNL/Devices/CudaCallable.h b/src/TNL/Devices/CudaCallable.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0a86a3e4f01a8ae112a45c7528f77e152289b04
--- /dev/null
+++ b/src/TNL/Devices/CudaCallable.h
@@ -0,0 +1,25 @@
+/***************************************************************************
+                          CudaCallable.h  -  description
+                             -------------------
+    begin                : Jun 20, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+// The __cuda_callable__ macro has to be in a separate header file to avoid
+// infinite loops by the #include directives.
+//
+// For example, the implementation of Devices::Cuda needs TNL_ASSERT_*
+// macros, which need __cuda_callable__ functions.
+
+#ifdef HAVE_MIC 
+   #define __cuda_callable__ __attribute__((target(mic)))
+#elif HAVE_CUDA
+   #define __cuda_callable__ __device__ __host__
+#else
+   #define __cuda_callable__
+#endif
diff --git a/src/TNL/Devices/CudaDeviceInfo.cpp b/src/TNL/Devices/CudaDeviceInfo.cpp
index 93061f8bd5ff1817c02f35b654de78f671f8c009..85a6604d87bba8655aac46609d4ae0db8dc24934 100644
--- a/src/TNL/Devices/CudaDeviceInfo.cpp
+++ b/src/TNL/Devices/CudaDeviceInfo.cpp
@@ -11,6 +11,7 @@
 #ifndef HAVE_CUDA
 
 #include <TNL/Devices/CudaDeviceInfo.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {   
@@ -64,6 +65,13 @@ getGlobalMemory( int deviceNum )
    return 0;
 }
 
+size_t
+CudaDeviceInfo::
+getFreeGlobalMemory()
+{
+   return 0;
+}
+
 int
 CudaDeviceInfo::
 getMemoryClockRate( int deviceNum )
@@ -99,6 +107,19 @@ getCudaCores( int deviceNum )
    return 0;
 }
 
+int
+CudaDeviceInfo::
+getRegistersPerMultiprocessor( int deviceNum )
+{
+   return 0;
+}
+
+void
+CudaDeviceInfo::
+writeDeviceInfo( Logger& logger )
+{
+}
+
 } // namespace Devices
 } // namespace TNL
 
diff --git a/src/TNL/Devices/CudaDeviceInfo.cu b/src/TNL/Devices/CudaDeviceInfo.cu
index 590347580373e26365ed110d8a83ed76d31b154f..56905df9675ef10b07ba40d1876215376ade611c 100644
--- a/src/TNL/Devices/CudaDeviceInfo.cu
+++ b/src/TNL/Devices/CudaDeviceInfo.cu
@@ -10,8 +10,10 @@
 
 #ifdef HAVE_CUDA
 
+#include <unordered_map>
+
 #include <TNL/Devices/CudaDeviceInfo.h>
-#include <TNL/Devices/Cuda.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {
@@ -79,6 +81,16 @@ getGlobalMemory( int deviceNum )
     return properties.totalGlobalMem;
 }
 
+size_t
+CudaDeviceInfo::
+getFreeGlobalMemory()
+{
+   size_t free = 0;
+   size_t total = 0;
+   cudaMemGetInfo( &free, &total );
+   return free;
+}
+
 int
 CudaDeviceInfo::
 getMemoryClockRate( int deviceNum )
@@ -101,9 +113,15 @@ int
 CudaDeviceInfo::
 getCudaMultiprocessors( int deviceNum )
 {
-    cudaDeviceProp properties;
-    cudaGetDeviceProperties( &properties, deviceNum );
-    return properties.multiProcessorCount;
+    // results are cached because they are used for configuration of some kernels
+    static std::unordered_map< int, int > results;
+    if( results.count( deviceNum ) == 0 ) {
+        cudaDeviceProp properties;
+        cudaGetDeviceProperties( &properties, deviceNum );
+        results.emplace( deviceNum, properties.multiProcessorCount );
+        return properties.multiProcessorCount;
+    }
+    return results[ deviceNum ];
 }
 
 int
@@ -117,17 +135,26 @@ getCudaCoresPerMultiprocessors( int deviceNum )
         case 1:   // Tesla generation, G80, G8x, G9x classes
             return 8;
         case 2:   // Fermi generation
-        switch( minor )
-        {
-            case 0:  // GF100 class
-                return 32;
-            case 1:  // GF10x class
-                return 48;
-        }
+            switch( minor )
+            {
+                case 0:  // GF100 class
+                    return 32;
+                case 1:  // GF10x class
+                    return 48;
+            }
         case 3: // Kepler generation -- GK10x, GK11x classes
             return 192;
         case 5: // Maxwell generation -- GM10x, GM20x classes
             return 128;
+        case 6: // Pascal generation
+            switch( minor )
+            {
+                case 0:  // GP100 class
+                    return 64;
+                case 1:  // GP10x classes
+                case 2:
+                    return 128;
+            }
         default:
             return -1;
     }
@@ -141,6 +168,50 @@ getCudaCores( int deviceNum )
            CudaDeviceInfo::getCudaCoresPerMultiprocessors( deviceNum );
 }
 
+int
+CudaDeviceInfo::
+getRegistersPerMultiprocessor( int deviceNum )
+{
+    // results are cached because they are used for configuration of some kernels
+    static std::unordered_map< int, int > results;
+    if( results.count( deviceNum ) == 0 ) {
+        cudaDeviceProp properties;
+        cudaGetDeviceProperties( &properties, deviceNum );
+        results.emplace( deviceNum, properties.regsPerMultiprocessor );
+        return properties.regsPerMultiprocessor;
+    }
+    return results[ deviceNum ];
+}
+
+void
+CudaDeviceInfo::
+writeDeviceInfo( Logger& logger )
+{
+   logger.writeParameter< String >( "CUDA GPU info", String("") );
+   // TODO: Printing all devices does not make sense until TNL can actually
+   //       use more than one device for computations. Printing only the active
+   //       device for now...
+//   int devices = getNumberOfDevices();
+//   writeParameter< int >( "Number of devices", devices, 1 );
+//   for( int i = 0; i < devices; i++ )
+//   {
+//      logger.writeParameter< int >( "Device no.", i, 1 );
+      int i = getActiveDevice();
+      logger.writeParameter< String >( "Name", getDeviceName( i ), 2 );
+      String deviceArch = String( getArchitectureMajor( i ) ) + "." +
+                              String( getArchitectureMinor( i ) );
+      logger.writeParameter< String >( "Architecture", deviceArch, 2 );
+      logger.writeParameter< int >( "CUDA cores", getCudaCores( i ), 2 );
+      double clockRate = ( double ) getClockRate( i ) / 1.0e3;
+      logger.writeParameter< double >( "Clock rate (in MHz)", clockRate, 2 );
+      double globalMemory = ( double ) getGlobalMemory( i ) / 1.0e9;
+      logger.writeParameter< double >( "Global memory (in GB)", globalMemory, 2 );
+      double memoryClockRate = ( double ) getMemoryClockRate( i ) / 1.0e3;
+      logger.writeParameter< double >( "Memory clock rate (in Mhz)", memoryClockRate, 2 );
+      logger.writeParameter< bool >( "ECC enabled", getECCEnabled( i ), 2 );
+//   }
+}
+
 } // namespace Devices
 } // namespace TNL
 
diff --git a/src/TNL/Devices/CudaDeviceInfo.h b/src/TNL/Devices/CudaDeviceInfo.h
index 3bc7475727faee79b016a4d881aee36cc36b8973..0b02daee53071d5899f4de14041e40f2da96adaa 100644
--- a/src/TNL/Devices/CudaDeviceInfo.h
+++ b/src/TNL/Devices/CudaDeviceInfo.h
@@ -11,9 +11,13 @@
 #pragma once
 
 #include <stdlib.h>
-#include <TNL/Devices/Cuda.h>
+
+#include <TNL/String.h>
 
 namespace TNL {
+
+class Logger;
+
 namespace Devices {
 
 class CudaDeviceInfo
@@ -34,6 +38,8 @@ class CudaDeviceInfo
 
       static size_t getGlobalMemory( int deviceNum );
 
+      static size_t getFreeGlobalMemory();
+
       static int getMemoryClockRate( int deviceNum );
 
       static bool getECCEnabled( int deviceNum );
@@ -44,8 +50,10 @@ class CudaDeviceInfo
 
       static int getCudaCores( int deviceNum );
 
+      static int getRegistersPerMultiprocessor( int deviceNum );
+
+      static void writeDeviceInfo( Logger& logger );
 };
 
 } // namespace Devices
 } // namespace TNL
-
diff --git a/src/TNL/Devices/Cuda_impl.h b/src/TNL/Devices/Cuda_impl.h
index 9c0d252a5a9e59458ca6cb915e4543dba6cfddbe..19bb9db873e3706cfbd9c3de18e9e69bf9bf7527 100644
--- a/src/TNL/Devices/Cuda_impl.h
+++ b/src/TNL/Devices/Cuda_impl.h
@@ -11,47 +11,68 @@
 #pragma once
 
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Exceptions/CudaBadAlloc.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 
 namespace TNL {
 namespace Devices {   
 
 __cuda_callable__ 
-inline int Cuda::getMaxGridSize()
+inline constexpr int Cuda::getMaxGridSize()
 {
    // TODO: make it preprocessor macro constant defined in tnlConfig
    return 65535;
 };
 
 __cuda_callable__
-inline int Cuda::getMaxBlockSize()
+inline constexpr int Cuda::getMaxBlockSize()
 {
    // TODO: make it preprocessor macro constant defined in tnlConfig
    return 1024;
 };
 
 __cuda_callable__ 
-inline int Cuda::getWarpSize()
+inline constexpr int Cuda::getWarpSize()
 {
    // TODO: make it preprocessor macro constant defined in tnlConfig
    return 32;
 }
 
+__cuda_callable__
+inline constexpr int Cuda::getNumberOfSharedMemoryBanks()
+{
+   // TODO: make it preprocessor macro constant defined in tnlConfig
+   return 32;
+}
+
+inline constexpr int Cuda::getGPUTransferBufferSize()
+{
+   return 1 << 20;
+}
+
 #ifdef HAVE_CUDA
-template< typename Index >
-__device__ Index Cuda::getGlobalThreadIdx( const Index gridIdx )
+__device__ inline int Cuda::getGlobalThreadIdx( const int gridIdx, const int gridSize )
 {
-   return ( gridIdx * Cuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+   return ( gridIdx * gridSize + blockIdx.x ) * blockDim.x + threadIdx.x;
 }
-#endif
 
+__device__ inline int Cuda::getGlobalThreadIdx_x( const dim3& gridIdx )
+{
+   return ( gridIdx.x * getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+}
 
-__cuda_callable__ 
-inline int Cuda::getNumberOfSharedMemoryBanks()
+__device__ inline int Cuda::getGlobalThreadIdx_y( const dim3& gridIdx )
 {
-   // TODO: make it preprocessor macro constant defined in tnlConfig
-   return 32;
+   return ( gridIdx.y * getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
 }
 
+__device__ inline int Cuda::getGlobalThreadIdx_z( const dim3& gridIdx )
+{
+   return ( gridIdx.z * getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
+}
+#endif
+
+
 template< typename ObjectType >
 ObjectType* Cuda::passToDevice( const ObjectType& object )
 {
@@ -59,23 +80,20 @@ ObjectType* Cuda::passToDevice( const ObjectType& object )
    ObjectType* deviceObject;
    if( cudaMalloc( ( void** ) &deviceObject,
                    ( size_t ) sizeof( ObjectType ) ) != cudaSuccess )
-   {
-      checkCudaDevice;
-      return 0;
-   }
+      throw Exceptions::CudaBadAlloc();
    if( cudaMemcpy( ( void* ) deviceObject,
                    ( void* ) &object,
                    sizeof( ObjectType ),
                    cudaMemcpyHostToDevice ) != cudaSuccess )
    {
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
       cudaFree( ( void* ) deviceObject );
+      TNL_CHECK_CUDA_DEVICE;
       return 0;
    }
    return deviceObject;
 #else
-   Assert( false, std::cerr << "CUDA support is missing." );
-   return 0;
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
@@ -88,26 +106,25 @@ ObjectType Cuda::passFromDevice( const ObjectType* object )
                ( void* ) &object,
                sizeof( ObjectType ),
                cudaMemcpyDeviceToHost );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
    return aux;
 #else
-   Assert( false, std::cerr << "CUDA support is missing." );
-   return 0;
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
 template< typename ObjectType >
 void Cuda::passFromDevice( const ObjectType* deviceObject,
-                              ObjectType& hostObject )
+                           ObjectType& hostObject )
 {
 #ifdef HAVE_CUDA
    cudaMemcpy( ( void* ) &hostObject,
                ( void* ) deviceObject,
                sizeof( ObjectType ),
                cudaMemcpyDeviceToHost );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
 #else
-   Assert( false, std::cerr << "CUDA support is missing." );
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
@@ -127,9 +144,9 @@ void Cuda::freeFromDevice( ObjectType* deviceObject )
 {
 #ifdef HAVE_CUDA
    cudaFree( ( void* ) deviceObject );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
 #else
-   Assert( false, std::cerr << "CUDA support is missing." );
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
@@ -140,25 +157,12 @@ __device__ Index Cuda::getInterleaving( const Index index )
    return index + index / Cuda::getNumberOfSharedMemoryBanks();
 }
 
-template< typename Element >
-__device__ getSharedMemory< Element >::operator Element*()
-{
-   extern __shared__ int __sharedMemory[];
-   return ( Element* ) __sharedMemory;
-};
-
-__device__ inline getSharedMemory< double >::operator double*()
-{
-   extern __shared__ double __sharedMemoryDouble[];
-   return ( double* ) __sharedMemoryDouble;
-};
-
-__device__ inline getSharedMemory< long int >::operator long int*()
+template< typename Element, size_t Alignment >
+__device__ Element* Cuda::getSharedMemory()
 {
-   extern __shared__ long int __sharedMemoryLongInt[];
-   return ( long int* ) __sharedMemoryLongInt;
-};
-
+   extern __shared__ __align__ ( Alignment ) unsigned char __sdata[];
+   return reinterpret_cast< Element* >( __sdata );
+}
 #endif /* HAVE_CUDA */
 
 } // namespace Devices
diff --git a/src/TNL/Devices/Host.cpp b/src/TNL/Devices/Host.cpp
index f46678c2d78219bceb01a1836b53d240f66c40dc..60f266734b1d6e1d8353bc8767f5b31a17bab48d 100644
--- a/src/TNL/Devices/Host.cpp
+++ b/src/TNL/Devices/Host.cpp
@@ -8,16 +8,31 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include <TNL/Devices/Host.h>
+#include <set>
+#include <iomanip>
+#include <cstring>
+#include <ctime>
+
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
 #ifdef HAVE_OPENMP
 #include <omp.h>
 #endif
+
+#include <TNL/tnlConfig.h>
+#include <TNL/Devices/Host.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Config/ParameterContainer.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {   
 
+int Host::numberOfProcessors( 0 );
+String Host::CPUModelName( "" );
+int Host::CPUThreads( 0 );
+int Host::CPUCores( 0 );
 bool Host::ompEnabled( true );
 int Host::maxThreadsCount( -1 );
 
@@ -26,6 +41,209 @@ String Host::getDeviceType()
    return String( "Devices::Host" );
 };
 
+
+String
+Host::getHostname( void )
+{
+   char host_name[ 256 ];
+   gethostname( host_name, 255 );
+   return String( host_name );
+}
+
+String
+Host::getArchitecture( void )
+{
+   utsname uts;
+   uname( &uts );
+   return String( uts.machine );
+}
+
+String
+Host::getSystemName( void )
+{
+   utsname uts;
+   uname( &uts );
+   return String( uts.sysname );
+}
+
+String
+Host::getSystemRelease( void )
+{
+   utsname uts;
+   uname( &uts );
+   return String( uts.release );
+}
+
+String
+Host::getCurrentTime( const char* format )
+{
+   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 String( ss.str().c_str() );
+   char buffer[1024];
+   std::strftime( buffer, 1024, format, localtime );
+   return String( buffer );
+}
+
+
+int
+Host::getNumberOfProcessors( void )
+{
+   if( numberOfProcessors == 0 )
+      parseCPUInfo();
+   return numberOfProcessors;
+}
+
+String
+Host::getOnlineCPUs( void )
+{
+   std::string online = readFile< std::string >( "/sys/devices/system/cpu/online" );
+   return String( online.c_str() );
+}
+
+int
+Host::getNumberOfCores( int cpu_id )
+{
+   if( CPUCores == 0 )
+      parseCPUInfo();
+   return CPUCores;
+}
+
+int
+Host::getNumberOfThreads( int cpu_id )
+{
+   if( CPUThreads == 0 )
+      parseCPUInfo();
+   return CPUThreads;
+}
+
+String
+Host::getCPUModelName( int cpu_id )
+{
+   if( CPUModelName == "" )
+      parseCPUInfo();
+   return CPUModelName;
+}
+
+int
+Host::getCPUMaxFrequency( int cpu_id )
+{
+   String fileName( "/sys/devices/system/cpu/cpu" );
+   fileName += String( cpu_id ) + "/cpufreq/cpuinfo_max_freq";
+   return readFile< int >( fileName );
+}
+
+CacheSizes
+Host::getCPUCacheSizes( int cpu_id )
+{
+   String directory( "/sys/devices/system/cpu/cpu" );
+   directory += String( cpu_id ) + "/cache";
+
+   CacheSizes sizes;
+   for( int i = 0; i <= 3; i++ ) {
+      const String cache = directory + "/index" + String( 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;
+}
+
+void
+Host::
+writeDeviceInfo( Logger& logger )
+{
+   logger.writeParameter< String >( "Host name:", getHostname() );
+   logger.writeParameter< String >( "System:", getSystemName() );
+   logger.writeParameter< String >( "Release:", getSystemRelease() );
+   logger.writeParameter< String >( "Architecture:", getArchitecture() );
+   logger.writeParameter< char* >( "TNL Compiler:", ( char* ) TNL_CPP_COMPILER_NAME );
+   // FIXME: generalize for multi-socket systems, here we consider only the first found CPU
+   const int cpu_id = 0;
+   const int threads = getNumberOfThreads( cpu_id );
+   const int cores = getNumberOfCores( cpu_id );
+   int threadsPerCore = 0;
+   if( cores > 0 )
+      threadsPerCore = threads / cores;
+   logger.writeParameter< String >( "CPU info", String("") );
+   logger.writeParameter< String >( "Model name:", getCPUModelName( cpu_id ), 1 );
+   logger.writeParameter< int >( "Cores:", cores, 1 );
+   logger.writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
+   logger.writeParameter< String >( "Max clock rate (in MHz):", getCPUMaxFrequency( cpu_id ) / 1000, 1 );
+   CacheSizes cacheSizes = getCPUCacheSizes( cpu_id );
+   String cacheInfo = String( cacheSizes.L1data ) + ", "
+                       + String( cacheSizes.L1instruction ) + ", "
+                       + String( cacheSizes.L2 ) + ", "
+                       + String( cacheSizes.L3 );
+   logger.writeParameter< String >( "Cache (L1d, L1i, L2, L3):", cacheInfo, 1 );
+}
+
+void
+Host::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();
+}
+
+
 size_t Host::getFreeMemory()
 {
    long pages = sysconf(_SC_PHYS_PAGES);
@@ -86,14 +304,22 @@ void Host::configSetup( Config::ConfigDescription& config, const String& prefix
 bool Host::setup( const Config::ParameterContainer& parameters,
                   const String& prefix )
 {
-   if( parameters.getParameter< bool >( prefix + "openmp-enabled" ) )
+   if( parameters.getParameter< bool >( prefix + "openmp-enabled" ) ) {
+#ifdef HAVE_OPENMP
       enableOMP();
+#else
+      std::cerr << "OpenMP is not supported - please recompile the TNL library with OpenMP." << std::endl;
+      return false;
+#endif
+   }
    else
       disableOMP();
-   setMaxThreadsCount( parameters.getParameter< int >( prefix + "openmp-max-threads" ) );
+   const int threadsCount = parameters.getParameter< int >( prefix + "openmp-max-threads" );
+   if( threadsCount > 1 && ! isOMPEnabled() )
+      std::cerr << "Warning: openmp-max-threads was set to " << threadsCount << ", but OpenMP is disabled." << std::endl;
+   setMaxThreadsCount( threadsCount );
    return true;
 }
 
 } // namespace Devices
 } // namespace TNL
-
diff --git a/src/TNL/Devices/Host.h b/src/TNL/Devices/Host.h
index bf41998ffc8ad761a7a707e12b5f64347841bc21..6c5c8a869321e24c4c4d19fc66ef4d7aea72b345 100644
--- a/src/TNL/Devices/Host.h
+++ b/src/TNL/Devices/Host.h
@@ -10,7 +10,8 @@
 
 #pragma once 
 
-#include <unistd.h>
+#include <fstream>
+
 #include <TNL/String.h>
 
 namespace TNL {
@@ -20,14 +21,39 @@ namespace Config {
    class ParameterContainer;
 }
 
+class Logger;
+
 namespace Devices {
 
+struct CacheSizes {
+   int L1instruction = 0;
+   int L1data = 0;
+   int L2 = 0;
+   int L3 = 0;
+};
+
 class Host
 {
    public:
 
       static String getDeviceType();
 
+      static String getHostname( void );
+      static String getArchitecture( void );
+      static String getSystemName( void );
+      static String getSystemRelease( void );
+      static String getCurrentTime( const char* format = "%a %b %d %Y, %H:%M:%S" );
+
+      static int    getNumberOfProcessors( void );
+      static String getOnlineCPUs( void );
+      static int    getNumberOfCores( int cpu_id );
+      static int    getNumberOfThreads( int cpu_id );
+      static String getCPUModelName( int cpu_id );
+      static int    getCPUMaxFrequency( int cpu_id );
+      static CacheSizes getCPUCacheSizes( int cpu_id );
+
+      static void writeDeviceInfo( Logger& logger );
+
       static size_t getFreeMemory();
  
       static void disableOMP();
@@ -58,12 +84,31 @@ class Host
                          const String& prefix = "" );
 
    protected:
+
+      static int numberOfProcessors;
+      static String CPUModelName;
+      static int CPUThreads;
+      static int CPUCores;
+   
+      static void parseCPUInfo( void );
+
+      template< typename ResultType >
+      static ResultType
+      readFile( const String & fileName )
+      {
+         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;
+      }
  
       static bool ompEnabled;
  
       static int maxThreadsCount;
-
-
 };
 
 } // namespace Devices
diff --git a/src/TNL/Devices/MIC.cpp b/src/TNL/Devices/MIC.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b16ac7854dd29ced0ed433228f5aa783d1f017ac
--- /dev/null
+++ b/src/TNL/Devices/MIC.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+                          MIC.cpp  -  description
+                             -------------------
+    begin                : Feb 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Vit Hanousek
+
+#include <TNL/Devices/MIC.h>
+
+namespace TNL {
+namespace Devices {
+	
+SmartPointersRegister MIC::smartPointersRegister;
+Timer MIC::smartPointersSynchronizationTimer;
+
+void MIC::insertSmartPointer( SmartPointer* pointer )
+{
+   smartPointersRegister.insert( pointer, -1 );
+}
+
+void MIC::removeSmartPointer( SmartPointer* pointer )
+{
+   smartPointersRegister.remove( pointer, -1 );
+}
+
+bool MIC::synchronizeDevice( int deviceId )
+{
+   smartPointersSynchronizationTimer.start();
+   bool b = smartPointersRegister.synchronizeDevice( deviceId );
+   smartPointersSynchronizationTimer.stop();
+   return b;
+}
+
+
+} // namespace Devices
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Devices/MIC.h b/src/TNL/Devices/MIC.h
new file mode 100644
index 0000000000000000000000000000000000000000..36678c0d27da1c873ee4bf0da2e71616c012d2bc
--- /dev/null
+++ b/src/TNL/Devices/MIC.h
@@ -0,0 +1,179 @@
+/***************************************************************************
+                          MIC.h  -  description
+                          -------------------
+    begin                : Nov 7, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Vit Hanousek
+
+#pragma once
+
+#include <iostream>
+#include <cstring>
+#include <unistd.h>
+#include <TNL/String.h>
+#include <TNL/Assert.h>
+#include <TNL/SmartPointersRegister.h>
+#include <TNL/Timer.h>
+
+#include <TNL/Devices/CudaCallable.h>
+
+
+namespace TNL {
+
+namespace Devices {
+    
+//useful macros from Intel's tutorials -- but we do not use it, becaouse it is tricky (system of maping variables CPU-MIC)
+#define ALLOC alloc_if(1) //alloac variable at begining of offloaded block -- default
+#define FREE free_if(1) // delete variable at the end of offloaded block -- default
+#define RETAIN free_if(0) //do not delete variable at the end of offladed block  
+#define REUSE alloc_if(0) //do not alloc variable at begin of offloaded block, reuse variable on MIC which was not deleted befeore
+
+//structure which hides pointer - bypass mapping of variables and addresses of arrays and allow get RAW addres of MIC memory to RAM
+template< typename Type >
+struct MICHider{
+    Type *pointer;
+};
+
+//inflatable structure -- structures can be copied to MIC - classes not (viz paper published after CSJP 2016 in Krakow)
+//object can be copied in side this structure and then copied into MIC memory
+template <unsigned int VELIKOST>
+struct MICStruct{
+	uint8_t data[VELIKOST];
+};
+
+//Macros which can make code better readeble --but they are tricky, creating variables with specific names...
+//version using inflatable structure
+#define TNLMICSTRUCT(bb,typ) Devices::MICStruct<sizeof(typ)> s ## bb; \
+                             memcpy((void*)& s ## bb,(void*)& bb,sizeof(typ));
+#define TNLMICSTRUCTOFF(bb,typ) s ## bb
+#define TNLMICSTRUCTUSE(bb,typ) typ * kernel ## bb = (typ*) &s ## bb;
+#define TNLMICSTRUCTALLOC(bb,typ) typ * kernel ## bb = (typ*) malloc (sizeof(typ)); \
+                                memcpy((void*)kernel ## bb,(void*) & s ## bb, sizeof(typ));
+
+//version which retypes pointer of object to pointer to array of uint8_t, 
+//object can be copied using uint8_t pointer as array with same length as object size
+#define TNLMICHIDE(bb,typ) uint8_t * u ## bb=(uint8_t *)&bb; \
+                           MICHider<typ> kernel ## bb;
+#define TNLMICHIDEALLOCOFF(bb,typ) in(u ## bb:length(sizeof(typ))) out(kernel ## bb)
+#define TNLMICHIDEALLOC(bb,typ) kernel ## bb.pointer=(typ*)malloc(sizeof(typ)); \
+                                memcpy((void*)kernel ## bb.pointer,(void*)u ## bb,sizeof(typ));
+#define TNLMICHIDEFREEOFF(bb,typ) in(kernel ## bb)
+#define TNLMICHIDEFREE(bb,typ) free((void*)kernel ## bb.pointer
+
+class MIC
+{
+   public:
+   
+        static String getDeviceType()
+        {
+            return String( "MIC" );
+        };
+        
+#ifdef HAVE_MIC  
+        
+       //useful debuging -- but produce warning
+       __cuda_callable__ static inline void CheckMIC(void)
+       {
+            #ifdef __MIC__
+                    std::cout<<"ON MIC"<<std::endl;
+            #else
+                    std::cout<<"ON CPU" <<std::endl;
+            #endif
+        };
+        
+       
+        //old copying funciton  -- deprecated
+        template <typename TYP>
+        static
+        TYP * passToDevice(TYP &objektCPU)
+        {
+                uint8_t * uk=(uint8_t *)&objektCPU; 
+                MICHider<TYP> ret;
+                
+                #pragma offload target(mic) in(uk:length(sizeof(TYP))) out(ret)
+                {
+                    ret.pointer=(TYP*)malloc(sizeof(TYP));
+                    std::memcpy((void*)ret.pointer,(void*)uk,sizeof(TYP));
+                }
+                return ret.pointer;
+                
+                std::cout << "Někdo mně volá :-D" <<std::endl;
+        };
+        
+        //old cleaning function -- deprecated
+        template <typename TYP>
+        static
+        void freeFromDevice(TYP *objektMIC)
+        {
+            MICHider<TYP> ptr;
+            ptr.pointer=objektMIC;
+            #pragma offload target(mic) in(ptr)
+            {
+                free((void*)ptr.pointer);
+            }
+        };
+        
+        static inline
+        void CopyToMIC(void* mic_ptr,void* ptr,size_t size)
+        {
+            uint8_t image[size];
+            std::memcpy((void*)&image,ptr,size);
+            Devices::MICHider<void> hide_ptr;
+            hide_ptr.pointer=mic_ptr;
+            #pragma offload target(mic) in(hide_ptr) in(image) in(size)
+            {
+                std::memcpy((void*)hide_ptr.pointer,(void*)&image,size);
+            }
+        };
+
+        static inline
+        void* AllocMIC(size_t size)
+        {
+            Devices::MICHider<void> hide_ptr;
+            #pragma offload target(mic) out(hide_ptr) in(size)
+            {
+                hide_ptr.pointer=malloc(size);
+            }
+            return hide_ptr.pointer;
+        };
+
+        static inline
+        void FreeMIC(void* ptr)
+        {
+                Devices::MICHider<void> hide_ptr;
+                hide_ptr.pointer=ptr;
+                #pragma offload target(mic) in(hide_ptr)
+                {
+                        free(hide_ptr.pointer);
+                }
+        };
+       
+        
+#endif
+        
+   static void insertSmartPointer( SmartPointer* pointer );
+   
+   static void removeSmartPointer( SmartPointer* pointer );
+   
+   // Negative deviceId means that CudaDeviceInfo::getActiveDevice will be
+   // called to get the device ID.
+   static bool synchronizeDevice( int deviceId = -1 );
+   
+   static Timer smartPointersSynchronizationTimer;
+   
+   protected:
+   
+   static SmartPointersRegister smartPointersRegister;
+
+};
+
+}//namespace Devices
+
+}//namespace TNL
+
+
diff --git a/src/TNL/Exceptions/CMakeLists.txt b/src/TNL/Exceptions/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..856f8c2fc73fd86f8e1530392bcb158dbaca5568
--- /dev/null
+++ b/src/TNL/Exceptions/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET( headers CudaBadAlloc.h
+             CudaRuntimeError.h
+             CudaSupportMissing.h
+             MICBadAlloc.h
+             MICSupportMissing.h )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Exceptions )
diff --git a/src/TNL/Exceptions/CudaBadAlloc.h b/src/TNL/Exceptions/CudaBadAlloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..4dc78c488e65fe6e57fcfb8d5672d2554f2262b9
--- /dev/null
+++ b/src/TNL/Exceptions/CudaBadAlloc.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+                          CudaBadAlloc.h  -  description
+                             -------------------
+    begin                : Jun 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include <new>
+
+namespace TNL {
+namespace Exceptions {
+
+struct CudaBadAlloc
+   : public std::bad_alloc
+{
+   CudaBadAlloc()
+   {
+#ifdef HAVE_CUDA
+      // Make sure to clear the CUDA error, otherwise the exception handler
+      // might throw another exception with the same error.
+      cudaGetLastError();
+#endif
+   }
+
+   const char* what() const throw()
+   {
+      return "Failed to allocate memory on the CUDA device: "
+             "most likely there is not enough space on the device memory.";
+   }
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/CudaRuntimeError.h b/src/TNL/Exceptions/CudaRuntimeError.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6773c23c03ac0ab97ef5e9b6ecc8884ac324255
--- /dev/null
+++ b/src/TNL/Exceptions/CudaRuntimeError.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+                          CudaRuntimeError.h  -  description
+                             -------------------
+    begin                : Jun 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include "CudaSupportMissing.h"
+
+namespace TNL {
+namespace Exceptions {
+
+#ifdef HAVE_CUDA
+   using CudaStatusType = cudaError;
+#else
+   using CudaStatusType = int;
+#endif
+
+class CudaRuntimeError
+   : public std::runtime_error
+{
+public:
+   CudaRuntimeError( CudaStatusType error_code )
+   : std::runtime_error( "CUDA ERROR " + std::to_string( (int) error_code ) + " (" + name( error_code ) + "): "
+                         + description( error_code ) + "." ),
+     code_( error_code )
+   {}
+
+   CudaRuntimeError( CudaStatusType error_code, const std::string& what_arg )
+   : std::runtime_error( "CUDA ERROR " + std::to_string( (int) error_code ) + " (" + name( error_code ) + "): "
+                         + description( error_code ) + ".\nDetails: " + what_arg ),
+     code_(error_code)
+   {}
+
+   CudaRuntimeError( CudaStatusType error_code, const char* file_name, int line )
+   : std::runtime_error( "CUDA ERROR " + std::to_string( (int) error_code ) + " (" + name( error_code ) + "): "
+                         + description( error_code ) + ".\nSource: line " + std::to_string( line )
+                         + " in " + file_name + ": " + description( error_code ) ),
+     code_(error_code)
+   {}
+
+   CudaStatusType code() const
+   {
+      return code_;
+   }
+
+private:
+   static std::string name( CudaStatusType error_code )
+   {
+#ifdef HAVE_CUDA
+      return cudaGetErrorName( error_code );
+#else
+      throw CudaSupportMissing();
+#endif
+   }
+
+   static std::string description( CudaStatusType error_code )
+   {
+#ifdef HAVE_CUDA
+      return cudaGetErrorString( error_code );
+#else
+      throw CudaSupportMissing();
+#endif
+   }
+
+   CudaStatusType code_;
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/CudaSupportMissing.h b/src/TNL/Exceptions/CudaSupportMissing.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a7f978a122a0c0f53f82a06d3dc03bbde40fd36
--- /dev/null
+++ b/src/TNL/Exceptions/CudaSupportMissing.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+                          CudaSupportMissing.h  -  description
+                             -------------------
+    begin                : Jun 18, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include <stdexcept>
+
+namespace TNL {
+namespace Exceptions {
+
+struct CudaSupportMissing
+   : public std::runtime_error
+{
+   CudaSupportMissing()
+   : std::runtime_error( "CUDA support is missing, but the program called a function which needs it. "
+                         "Please recompile the program with CUDA support." )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/MICBadAlloc.h b/src/TNL/Exceptions/MICBadAlloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8f3a9157c54d8155652a42a700ad71a221aa201
--- /dev/null
+++ b/src/TNL/Exceptions/MICBadAlloc.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+                          MICBadAlloc.h  -  description
+                             -------------------
+    begin                : Jul 31, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include <new>
+
+namespace TNL {
+namespace Exceptions {
+
+struct MICBadAlloc
+   : public std::bad_alloc
+{
+   const char* what() const throw()
+   {
+      return "Failed to allocate memory on the MIC device: "
+             "most likely there is not enough space on the device memory.";
+   }
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/MICSupportMissing.h b/src/TNL/Exceptions/MICSupportMissing.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d4260e6addbbb9dd89a7c9d5a07833485c6a0c2
--- /dev/null
+++ b/src/TNL/Exceptions/MICSupportMissing.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+                          MICSupportMissing.h  -  description
+                             -------------------
+    begin                : Jul 31, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include <stdexcept>
+
+namespace TNL {
+namespace Exceptions {
+
+struct MICSupportMissing
+   : public std::runtime_error
+{
+   MICSupportMissing()
+   : std::runtime_error( "MIC support is missing, but the program called a function which needs it. "
+                         "Please recompile the program with MIC support." )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Experimental/Arithmetics/CMakeLists.txt b/src/TNL/Experimental/Arithmetics/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Experimental/Arithmetics/Real.h b/src/TNL/Experimental/Arithmetics/Real.h
index 96d8369ef62d3211cc8182833569c85e7e7b6a44..7f0943147705757f3eb0c745b6e0025dbd763614 100644
--- a/src/TNL/Experimental/Arithmetics/Real.h
+++ b/src/TNL/Experimental/Arithmetics/Real.h
@@ -11,7 +11,7 @@
 #pragma once
 
 #include <iostream>
-#include <math.h>
+#include <cmath>
 #include <TNL/Experimental/Arithmetics/FlopsCounter.h>
 
 namespace TNL {
@@ -313,105 +313,105 @@ template< class T > const Real< T > fabs( const Real< T >& v )
 template< class T > const Real< T > sqrt( const Real< T >& v )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::sqrt( v. Data() ) );
+   return Real< T >( std::sqrt( v. Data() ) );
 };
 
 template< class T > const Real< T > pow( const Real< T >& x, const Real< T >& exp )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::pow( x. Data(), exp. Data() ) );
+   return Real< T >( std::pow( x. Data(), exp. Data() ) );
 };
 
 template< class T > const Real< T > pow( const Real< T >& x, const T& exp )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::pow( x. Data(), exp ) );
+   return Real< T >( std::pow( x. Data(), exp ) );
 };
 
 template< class T > const Real< T > cos( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::cos( x. Data() ) );
+   return Real< T >( std::cos( x. Data() ) );
 };
 
 template< class T > const Real< T > sin( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::sin( x. Data() ) );
+   return Real< T >( std::sin( x. Data() ) );
 };
 
 template< class T > const Real< T > tan( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( tan( x. Data() ) );
+   return Real< T >( std::tan( x. Data() ) );
 };
 
 template< class T > const Real< T > acos( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( acos( x. Data() ) );
+   return Real< T >( std::acos( x. Data() ) );
 };
 
 template< class T > const Real< T > asin( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( asin( x. Data() ) );
+   return Real< T >( std::asin( x. Data() ) );
 };
 
 template< class T > const Real< T > atan( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( atan( x. Data() ) );
+   return Real< T >( std::atan( x. Data() ) );
 };
 
 template< class T > const Real< T > atan2( const Real< T >& x, const Real< T >& exp )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( atan2( x. Data(), exp. Data() ) );
+   return Real< T >( std::atan2( x. Data(), exp. Data() ) );
 };
 
 template< class T > const Real< T > atan2( const Real< T >& x, const T& exp )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( atan2( x. Data(), exp ) );
+   return Real< T >( std::atan2( x. Data(), exp ) );
 };
 
 
 template< class T > const Real< T > cosh( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( cosh( x. Data() ) );
+   return Real< T >( std::cosh( x. Data() ) );
 };
 
 template< class T > const Real< T > sinh( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( sinh( x. Data() ) );
+   return Real< T >( std::sinh( x. Data() ) );
 };
 
 template< class T > const Real< T > tanh( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( ::tanh( x. Data() ) );
+   return Real< T >( std::tanh( x. Data() ) );
 };
 
 
 template< class T > const Real< T > exp( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( exp( x. Data() ) );
+   return Real< T >( std::exp( x. Data() ) );
 };
 
 template< class T > const Real< T > log( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( log( x. Data() ) );
+   return Real< T >( std::log( x. Data() ) );
 };
 
 template< class T > const Real< T > log10( const Real< T >& x )
 {
    tnl_flops_counter. recordFunction();
-   return Real< T >( log10( x. Data() ) );
+   return Real< T >( std::log10( x. Data() ) );
 };
 
 template< class T >
diff --git a/src/TNL/Experimental/CMakeLists.txt b/src/TNL/Experimental/CMakeLists.txt
old mode 100755
new mode 100644
index acb1a43c37120ab468bea9a3e1126c319d2dca92..47fc9efa44f92699b64e247af1778ad83e6cebfa
--- a/src/TNL/Experimental/CMakeLists.txt
+++ b/src/TNL/Experimental/CMakeLists.txt
@@ -1,2 +1,3 @@
 ADD_SUBDIRECTORY( Arithmetics )
 ADD_SUBDIRECTORY( Multimaps )
+ADD_SUBDIRECTORY( Hamilton-Jacobi )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..538e5d99ccaacd6892be2a378da2f19349ec3fa4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_SUBDIRECTORY( Operators )
+#ADD_SUBDIRECTORY( Solvers )
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8ee63a0ac16a88e13ecb964013435160464e38b1
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY( Hamilton-Jacobi )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bce61025f2bae120464881216c62091e40604836
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_SUBDIRECTORY( Godunov )
+ADD_SUBDIRECTORY( Godunov-Eikonal )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..115fd1c2cde483c4fbfe64951210d69827976d2b
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt
@@ -0,0 +1,18 @@
+set( headers godunov.h
+	     godunov1D_impl.h
+             godunov2D_impl.h
+             godunov3D_impl.h)
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov )
+
+if( BUILD_CUDA)
+      set( tnl_implementation_operators_godunov_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_implementation_operators_godunov_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Godunov/ )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cebf0ea9a2608526cff1dcf1290e41fa4f7b083
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h
@@ -0,0 +1,264 @@
+/***************************************************************************
+                          godunov.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once
+
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+		    typename Real,
+		    typename Index >
+class godunovEikonalScheme
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+      static String getType();
+   
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& f ) const
+      {
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1 >();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
+
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex< 1 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1 >() ];
+         
+         if( f > 0.0 )
+         {
+            RealType xf = negativePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = positivePart( ( u_c - u_w ) * hx_inv );
+            
+            if( xb + xf > 0.0 )
+               xf = 0.0;
+            else
+               xb = 0.0;
+
+            return sqrt( xf * xf + xb * xb );
+         }
+         else if( f < 0.0 )
+         {
+            RealType xf = positivePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = negativePart( ( u_c - u_w ) * hx_inv );
+
+            if( xb + xf > 0.0 )
+               xb = 0.0;
+            else
+               xf = 0.0;
+
+            return sqrt( xf * xf + xb * xb );
+
+         }
+         else
+         {
+            return 0.0;
+         }
+      }
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+      static String getType();
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& f ) const
+      {
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
+         const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts<  0, -1 >();
+
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();   
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex<  1,  0 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1,  0 >() ];
+         const RealType& u_n = u[ neighborEntities.template getEntityIndex<  0,  1 >() ];
+         const RealType& u_s = u[ neighborEntities.template getEntityIndex<  0, -1 >() ];
+
+         if( f > 0.0 )
+         {
+            RealType xf = negativePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = positivePart( ( u_c - u_w ) * hx_inv );
+            RealType yf = negativePart( ( u_n - u_c ) * hy_inv );
+            RealType yb = positivePart( ( u_c - u_s ) * hy_inv );
+            
+            if( xb + xf > 0.0 )
+               xf = 0.0;
+            else
+               xb = 0.0;
+
+            if( yb + yf > 0.0 )
+               yf = 0.0;
+            else
+               yb = 0.0;
+
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb );
+         }
+         else if( f < 0.0 )
+         {
+            RealType xf = positivePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = negativePart( ( u_c - u_w ) * hx_inv );
+            RealType yf = positivePart( ( u_n - u_c ) * hy_inv );
+            RealType yb = negativePart( ( u_c - u_s ) * hy_inv );
+
+            if( xb + xf > 0.0 )
+               xb = 0.0;
+            else
+               xf = 0.0;
+
+            if( yb + yf > 0.0 )
+               yb = 0.0;
+            else
+               yf = 0.0;
+
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb );
+
+         }
+         else
+         {
+            return 0.0;
+         }
+      }
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;   
+
+      static String getType();
+   
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& f ) const
+      {
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >();
+         const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >();
+         const RealType& hz_inv = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >();
+
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ];
+         const RealType& u_n = u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ];
+         const RealType& u_s = u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ];
+         const RealType& u_t = u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ];
+         const RealType& u_b = u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ];
+         
+         if( f > 0.0 )
+         {
+            RealType xf = negativePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = positivePart( ( u_c - u_w ) * hx_inv );
+            RealType yf = negativePart( ( u_n - u_c ) * hy_inv );
+            RealType yb = positivePart( ( u_c - u_s ) * hy_inv );
+            RealType zf = negativePart( ( u_t - u_c ) * hz_inv );
+            RealType zb = positivePart( ( u_c - u_b ) * hz_inv );
+            
+            if( xb + xf > 0.0 )
+               xf = 0.0;
+            else
+               xb = 0.0;
+
+            if( yb + yf > 0.0 )
+               yf = 0.0;
+            else
+               yb = 0.0;
+
+            if( zb + zf > 0.0 )
+               zf = 0.0;
+            else
+               zb = 0.0;
+
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb );
+         }
+         else if( f < 0.0 )
+         {
+            RealType xf = positivePart( ( u_e - u_c ) * hx_inv );
+            RealType xb = negativePart( ( u_c - u_w ) * hx_inv );
+            RealType yf = positivePart( ( u_n - u_c ) * hy_inv );
+            RealType yb = negativePart( ( u_c - u_s ) * hy_inv );
+            RealType zf = positivePart( ( u_t - u_c ) * hz_inv );
+            RealType zb = negativePart( ( u_c - u_b ) * hz_inv );
+
+            if( xb + xf > 0.0 )
+               xb = 0.0;
+            else
+               xf = 0.0;
+
+            if( yb + yf > 0.0 )
+               yb = 0.0;
+            else
+               yf = 0.0;
+
+            if( zb + zf > 0.0 )
+               zb = 0.0;
+            else
+               zf = 0.0;
+
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb );
+         }
+         else
+         {
+            return 0.0;
+         }
+      }
+};
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bb9c4e3b4fb36d9e9982f8abcead16a1e5dfdb16
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt
@@ -0,0 +1,24 @@
+set( headers godunovEikonal.h
+	     parallelGodunovEikonal.h
+	     parallelGodunovMap.h
+	     godunovEikonal1D_impl.h
+             godunovEikonal2D_impl.h
+             godunovEikonal3D_impl.h
+             parallelGodunovEikonal1D_impl.h
+             parallelGodunovEikonal2D_impl.h
+             parallelGodunovEikonal3D_impl.h
+             parallelGodunovMap2D_impl.h)
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov-eikonal )
+
+if( BUILD_CUDA)
+      set( tnl_implementation_operators_godunov-eikonal_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_implementation_operators_godunov-eikonal_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Godunov-Eikonal/ )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h
new file mode 100644
index 0000000000000000000000000000000000000000..fcff6b36aa023b548972117521b33b772029a838
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h
@@ -0,0 +1,185 @@
+/***************************************************************************
+                          godunov.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <matrices/tnlCSRMatrix.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/tnlSolverMonitor.h>
+#include <core/tnlLogger.h>
+#include <TNL/Containers/Vector.h>
+#include <core/mfilename.h>
+#include <mesh/tnlGrid.h>
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class godunovEikonalScheme
+{
+};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 1, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+
+	static String getType();
+
+	RealType positivePart(const RealType arg) const;
+
+	RealType negativePart(const RealType arg) const;
+
+	RealType sign(const RealType x, const RealType eps) const;
+   
+   template< typename PreimageFunction, typename MeshEntity >
+   __cuda_callable__
+    Real operator()( const PreimageFunction& u,
+                     const MeshEntity& entity,
+                     const RealType& time = 0.0 ) const;
+
+	bool init( const Config::ParameterContainer& parameters );
+
+
+protected:
+
+	MeshType originalMesh;
+
+	DofVectorType dofVector;
+
+	RealType h;
+
+	RealType epsilon;
+
+
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+      static String getType();
+
+      RealType positivePart(const RealType arg) const;
+
+      RealType negativePart(const RealType arg) const;
+
+      RealType sign(const RealType x, const Real eps) const;
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+       Real operator()( const PreimageFunction& u,
+                        const MeshEntity& entity,
+                        const RealType& time = 0.0 ) const;
+
+      bool init( const Config::ParameterContainer& parameters );
+
+   protected:
+
+      MeshType originalMesh;
+
+      DofVectorType dofVector;
+
+      RealType hx;
+      RealType hy;
+
+      RealType epsilon;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+      static String getType();
+
+      RealType positivePart(const RealType arg) const;
+
+      RealType negativePart(const RealType arg) const;
+
+      RealType sign(const RealType x, const Real eps) const;
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+
+      bool init( const Config::ParameterContainer& parameters );
+
+
+   protected:
+
+      MeshType originalMesh;
+
+      DofVectorType dofVector;
+
+      RealType hx;
+      RealType hy;
+      RealType hz;
+
+      RealType epsilon;
+
+};
+
+#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal1D_impl.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal2D_impl.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal3D_impl.h>
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..308cfe93e7292e3660d305e9bd91e7e7b72716c5
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h
@@ -0,0 +1,165 @@
+/***************************************************************************
+                          godunov1D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real  godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if(eps == 0.0)
+		return 0.0;
+
+	return sin( ( M_PI * x ) / (2 * eps) );
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   h = originalMesh.template getSpaceSteps().x();
+	   cout << "h = " << h << endl;
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=h;
+
+	   /*dofVector. setSize( this->mesh.getDofs() );*/
+
+	   return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String godunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "godunovEikonalScheme< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+/*
+	RealType nabla, xb, xf, signui;
+
+	signui = sign(u[cellIndex],epsilon);
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else if (signui < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else
+*/	   {
+		   return 0.0;
+	   }
+
+}
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b4dfdcef01ac7adec0be39f0b8f088bfbed758a
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+                          godunov2D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 GODUNOVEIKONAL2D_IMPL_H_
+#define GODUNOVEIKONAL2D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real  godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if ( eps == 0.0)
+		return 0.0;
+
+	return sin((M_PI*x)/(2.0*eps));
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+
+
+	   hx = originalMesh.template getSpaceStepsProducts< 1, 0 >();
+	   hy = originalMesh.template getSpaceStepsProducts< 0, 1 >();
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=sqrt( hx*hx + hy*hy );
+
+//	   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String godunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "tnlLinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+/*
+	RealType nabla, xb, xf, yb, yf, signui;
+
+	signui = sign(u[cellIndex],epsilon);
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yf = 0.0;
+		   else
+			   yb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else if (signui < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yb = 0.0;
+		   else
+			   yf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else
+*/	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* GODUNOVEIKONAL2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d5bd0442a0ecd9c920df520cb41ccd8f83b7932
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h
@@ -0,0 +1,196 @@
+/***************************************************************************
+                          godunov3D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 GODUNOVEIKONAL3D_IMPL_H_
+#define GODUNOVEIKONAL3D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real  godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if ( eps == 0.0)
+		return 0.0;
+
+	return sin((M_PI*x)/(2.0*eps));
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   hx = originalMesh.getSpaceSteps().x();
+	   hy = originalMesh.getSpaceSteps().y();
+	   hz = originalMesh.getSpaceSteps().z();
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=sqrt( hx*hx + hy*hy +hz*hz );
+
+	//   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String godunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "tnlLinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+/*
+	RealType nabla, xb, xf, yb, yf, zb, zf, signui;
+
+	signui = sign(u[cellIndex],epsilon);
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+		   zf = negativePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz);
+		   zb = positivePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yf = 0.0;
+		   else
+			   yb = 0.0;
+
+		   if(zb + zf > 0.0)
+			   zf = 0.0;
+		   else
+			   zb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else if (signui < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+		   zf = positivePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz);
+		   zb = negativePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yb = 0.0;
+		   else
+			   yf = 0.0;
+
+		   if(zb + zf > 0.0)
+			   zb = 0.0;
+		   else
+			   zf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else
+*/	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* GODUNOVEIKONAL3D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h
new file mode 100644
index 0000000000000000000000000000000000000000..f462245848757f6ccf9b9349ac4baa38cb613e4b
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h
@@ -0,0 +1,268 @@
+/***************************************************************************
+                          parallelGodunovEikonal.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVEIKONAL_H_
+#define PARALLELGODUNOVEIKONAL_H_
+
+#include <matrices/tnlCSRMatrix.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/tnlSolverMonitor.h>
+#include <core/tnlLogger.h>
+#include <TNL/Containers/Vector.h>
+#include <core/mfilename.h>
+#include <mesh/tnlGrid.h>
+#include <core/tnlCuda.h>
+#include <mesh/grids/tnlGridEntity.h>
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class parallelGodunovEikonalScheme
+{
+};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 1, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType sign(const RealType x, const RealType eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+	MeshType originalMesh;
+
+	DofVectorType dofVector;
+
+	RealType h;
+
+
+
+
+};
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType sign(const RealType x, const Real eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+                   const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities) const;
+
+ #ifdef HAVE_CUDA
+    __device__
+ #endif
+    Real getValueDev( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const RealType* u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+                   const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+ 	MeshType originalMesh;
+
+    DofVectorType dofVector;
+
+    RealType hx, ihx;
+    RealType hy, ihy;
+
+
+
+
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType sign(const RealType x, const Real eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+  	  	  	       const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities  ) const;
+
+#ifdef HAVE_CUDA
+   __device__
+#endif
+   Real getValueDev( const MeshType& mesh,
+                  const IndexType cellIndex,
+                  const CoordinatesType& coordinates,
+                  const RealType* u,
+                  const RealType& time,
+                  const IndexType boundaryCondition,
+ 	  	  	      const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities ) const;
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+ 	MeshType originalMesh;
+
+    DofVectorType dofVector;
+
+    RealType hx, ihx;
+    RealType hy, ihy;
+    RealType hz, ihz;
+
+};
+
+
+
+//#include <operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal2D_impl.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal3D_impl.h>
+
+
+#endif /* PARALLELGODUNOVEIKONAL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2e5c549fdf97c68ef3f4c4adf82e261dd85f576
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h
@@ -0,0 +1,170 @@
+/***************************************************************************
+                          parallelGodunovEikonal1D_impl.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVEIKONAL1D_IMPL_H_
+#define PARALLELGODUNOVEIKONAL1D_IMPL_H_
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real  parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if(eps == 0.0)
+		return 0.0;
+
+	return sin( ( M_PI * x ) / (2 * eps) );
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   h = originalMesh.template getSpaceStepsProducts< 1, 0 >();
+	   cout << "h = " << h << endl;
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=h;
+
+	   /*dofVector. setSize( this->mesh.getDofs() );*/
+
+	   return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "parallelGodunovEikonalScheme< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition ) const
+{
+/*
+	RealType nabla, xb, xf, signui;
+
+	signui = sign(u[cellIndex],epsilon);
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else if (signui < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return signui*(1.0 - nabla);
+	   }
+	   else
+*/	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* PARALLELGODUNOVEIKONAL1D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..5ba9e3f781b5078f71acee19cd754364bca32b50
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h
@@ -0,0 +1,484 @@
+/***************************************************************************
+                          parallelGodunovEikonal2D_impl.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVEIKONAL2D_IMPL_H_
+#define PARALLELGODUNOVEIKONAL2D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real  parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return -arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	if (x < -eps)
+		return (-1.0);
+
+	if ( x == 0.0)
+		return 0.0;
+
+	return sin(/*(M_PI*x)/(2.0*eps)	*/(M_PI/2.0)*(x/eps));
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+bool parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   //MeshType originalMesh;
+	   if( ! originalMesh.load( meshFile ) )
+	   {
+		   //cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+
+
+	   hx = originalMesh.template getSpaceStepsProducts< 1, 0 >();
+	   ihx = 1.0/hx;
+	   hy = originalMesh.template getSpaceStepsProducts< 0, 1 >();
+	   ihy = 1.0/hy;
+
+	   this->epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   this->epsilon *=sqrt( hx*hx + hy*hy );
+
+//	   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+String parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "parallelGodunovEikonalScheme< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	  	  	  	  	  	  	  	  	                     const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities ) const
+{
+
+
+	if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or
+		 (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or
+		 (coordinates.y() == 0 && (boundaryCondition & 8)) or
+		 (coordinates.y() == mesh.getDimensions().y() - 1  && (boundaryCondition & 1)))
+		 /*and
+		 !(		 (coordinates.y() == 0 or coordinates.y() == mesh.getDimensions().y() - 1)
+				 and
+				 ( coordinates.x() == 0 or coordinates.x() == mesh.getDimensions().x() - 1)
+		  )*/
+		)
+	{
+		return 0.0;
+	}
+
+
+	//-----------------------------------
+
+	RealType signui;
+	signui = sign(u[cellIndex],this->epsilon);
+
+
+#ifdef HAVE_CUDA
+	//printf("%d   :    %d ;;;; %d   :   %d  , %f \n",threadIdx.x, mesh.getDimensions().x() , threadIdx.y,mesh.getDimensions().y(), epsilon );
+#endif
+
+	RealType xb = u[cellIndex];
+	RealType xf = -u[cellIndex];
+	RealType yb = u[cellIndex];
+	RealType yf = -u[cellIndex];
+	RealType a,b,c;
+
+
+	   if(coordinates.x() == mesh.getDimensions().x() - 1)
+		   xf += u[neighborEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighborEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighborEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighborEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighborEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+
+
+	   //xb *= ihx;
+	   //xf *= ihx;
+	  // yb *= ihy;
+	   //yf *= ihy;
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart(xf);
+
+		   xb = positivePart(xb);
+
+		   yf = negativePart(yf);
+
+		   yb = positivePart(yb);
+
+	   }
+	   else if(signui < 0.0)
+	   {
+
+		   xb = negativePart(xb);
+
+		   xf = positivePart(xf);
+
+		   yb = negativePart(yb);
+
+		   yf = positivePart(yf);
+	   }
+
+
+	   if(xb - xf > 0.0)
+		   a = xb;
+	   else
+		   a = xf;
+
+	   if(yb - yf > 0.0)
+		   b = yb;
+	   else
+		   b = yf;
+
+	   c =(1.0 - sqrt(a*a+b*b)*ihx );
+
+	   if(sign(c) > 0.0 )
+		   return sign(u[cellIndex])*c;
+	   else
+		   return signui*c;
+
+	   //--------------------------------------------------
+
+//
+//
+//
+//	RealType acc = hx*hy*hx*hy;
+//
+//	RealType nabla, xb, xf, yb, yf, signui;
+//
+//	signui = sign(u[cellIndex],this->epsilon);
+//
+//
+//	//if(fabs(u[cellIndex]) < acc) return 0.0;
+//
+//	   if(signui > 0.0)
+//	   {
+//	/**/ /*  if(boundaryCondition & 2)
+//			   xf = (u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx;
+//		   else *//*if(boundaryCondition & 4)
+//			   xf = 0.0;
+//		   else /**/if(coordinates.x() == mesh.getDimensions().x() - 1)
+//			   xf = negativePart((u[neighborEntities.template getEntityIndex< -1,  0 >()] - u[cellIndex])*ihx);
+//		   else
+//			   xf = negativePart((u[neighborEntities.template getEntityIndex< 1,  0 >()] - u[cellIndex])*ihx);
+//
+//	/**/ /*  if(boundaryCondition & 4)
+//			   xb = (u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])*ihx;
+//		   else *//*if(boundaryCondition & 2)
+//			   xb = 0.0;
+//		   else /**/if(coordinates.x() == 0)
+//			   xb = positivePart((u[cellIndex] - u[mesh.template getCellNextToCell<+1,0>( cellIndex )])*ihx);
+//		   else
+//			   xb = positivePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< -1,  0 >()])*ihx);
+//
+//	/**/  /* if(boundaryCondition & 1)
+//			   yf = (u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])*ihy;
+//		   else *//*if(boundaryCondition & 8)
+//			   yf = 0.0;
+//		   else /**/if(coordinates.y() == mesh.getDimensions().y() - 1)
+//			   yf = negativePart((u[neighborEntities.template getEntityIndex< 0,  -1 >()] - u[cellIndex])*ihy);
+//		   else
+//			   yf = negativePart((u[neighborEntities.template getEntityIndex< 0,  1 >()] - u[cellIndex])*ihy);
+//
+//	/**/  /* if(boundaryCondition & 8)
+//			   yb = (u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])*ihy;
+//		   else *//*if(boundaryCondition & 1)
+//			   yb = 0.0;
+//		   else /**/if(coordinates.y() == 0)
+//			   yb = positivePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< 0,  1 >()])*ihy);
+//		   else
+//			   yb = positivePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< 0,  -1 >()])*ihy);
+//
+//		   if(xb - xf > 0.0)
+//			   xf = 0.0;
+//		   else
+//			   xb = 0.0;
+//
+//		   if(yb - yf > 0.0)
+//			   yf = 0.0;
+//		   else
+//			   yb = 0.0;
+//
+//		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+//		   if(fabs(1.0-nabla) < acc)
+//			   return 0.0;
+//		   return signui*(1.0 - nabla);
+//	   }
+//	   else if (signui < 0.0)
+//	   {
+//
+//	/**/  /* if(boundaryCondition & 2)
+//			   xf = (u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])*ihx;
+//		   else*//* if(boundaryCondition & 4)
+//			   xf = 0.0;
+//		   else /**/if(coordinates.x() == mesh.getDimensions().x() - 1)
+//			   xf = positivePart((u[neighborEntities.template getEntityIndex< -1,  0 >()] - u[cellIndex])*ihx);
+//		   else
+//			   xf = positivePart((u[neighborEntities.template getEntityIndex< 1,  0 >()] - u[cellIndex])*ihx);
+//
+//	/**/  /* if(boundaryCondition & 4)
+//			   xb = (u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])*ihx;
+//		   else*//* if(boundaryCondition & 2)
+//			   xb = 0.0;
+//		   else /**/if(coordinates.x() == 0)
+//			   xb = negativePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< 1,  0 >()])*ihx);
+//		   else
+//			   xb = negativePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< -1,  0 >()])*ihx);
+//
+//	/**/ /*  if(boundaryCondition & 1)
+//			   yf = (u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])*ihy;
+//		   else *//*if(boundaryCondition & 8)
+//			   yf = 0.0;
+//		   else /**/if(coordinates.y() == mesh.getDimensions().y() - 1)
+//			   yf = positivePart((u[neighborEntities.template getEntityIndex< 0,  -1 >()] - u[cellIndex])*ihy);
+//		   else
+//			   yf = positivePart((u[neighborEntities.template getEntityIndex< 0,  1 >()] - u[cellIndex])*ihy);
+//
+//	/**/  /* if(boundaryCondition & 8)
+//			   yb = (u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])*ihy;
+//		   else*//* if(boundaryCondition & 1)
+//			   yb = 0.0;
+//		   else /**/if(coordinates.y() == 0)
+//			   yb = negativePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< 0,  1 >()])*ihy);
+//		   else
+//			   yb = negativePart((u[cellIndex] - u[neighborEntities.template getEntityIndex< 0,  -1 >()])*ihy);
+//
+//
+//		   if(xb - xf > 0.0)
+//			   xf = 0.0;
+//		   else
+//			   xb = 0.0;
+//
+//		   if(yb - yf > 0.0)
+//			   yf = 0.0;
+//		   else
+//			   yb = 0.0;
+//
+//		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+//
+//		   if(fabs(1.0-nabla) < acc)
+//			   return 0.0;
+//		   return signui*(1.0 - nabla);
+//	   }
+//	   else
+//	   {
+//		   return 0.0;
+//	   }
+
+}
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+
+#ifdef HAVE_CUDA
+__device__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real* u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	  	  	  	  	  	  	  	  	                     const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities) const
+{
+
+	RealType signui;
+	if(boundaryCondition == 0)
+		signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon);
+	else
+		signui = sign(u[cellIndex]);
+
+	RealType xb = u[cellIndex];
+	RealType xf = -u[cellIndex];
+	RealType yb = u[cellIndex];
+	RealType yf = -u[cellIndex];
+	RealType a,b/*,c*/;
+
+
+	   if(coordinates.x() == mesh.getDimensions().x() - 1)
+		   xf += u[neighborEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighborEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighborEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighborEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighborEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart(xf);
+
+		   xb = positivePart(xb);
+
+		   yf = negativePart(yf);
+
+		   yb = positivePart(yb);
+
+	   }
+	   else if(signui < 0.0)
+	   {
+
+		   xb = negativePart(xb);
+
+		   xf = positivePart(xf);
+
+		   yb = negativePart(yb);
+
+		   yf = positivePart(yf);
+	   }
+
+
+	   if(xb > xf)
+		   a = xb;
+	   else
+		   a = xf;
+
+	   if(yb > yf)
+		   b = yb;
+	   else
+		   b = yf;
+
+//	   c =(1.0 - sqrt(a*a+b*b)*ihx );
+
+//	   if(c > 0.0 )
+//		   return sign(u[cellIndex])*c;
+//	   else
+		   return signui*(1.0 - sqrt(a*a+b*b)*ihx );
+}
+
+
+#endif /* PARALLELGODUNOVEIKONAL2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..a352a07375a6457da3cff77a7f89dde88c94e8f7
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h
@@ -0,0 +1,370 @@
+/***************************************************************************
+                          parallelGodunovEikonal3D_impl.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVEIKONAL3D_IMPL_H_
+#define PARALLELGODUNOVEIKONAL3D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real  parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return -arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	if (x < -eps)
+		return (-1.0);
+
+	if ( x == 0.0)
+		return 0.0;
+
+	return sin((M_PI/2.0)*(x/eps));
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   hx = originalMesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	   hy = originalMesh.template getSpaceStepsProducts< 0, 1, 0 >();
+	   hz = originalMesh.template getSpaceStepsProducts< 0, 0, 1 >();
+	   ihx = 1.0/hx;
+	   ihy = 1.0/hy;
+	   ihz = 1.0/hz;
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=sqrt( hx*hx + hy*hy + hz*hz );
+
+	//   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "tnlLinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	          	  	  	  	  	  	  	  	  	  	                     const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities  ) const
+{
+	if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or
+		 (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or
+		 (coordinates.y() == 0 && (boundaryCondition & 8)) or
+		 (coordinates.y() == mesh.getDimensions().y() - 1  && (boundaryCondition & 1)) or
+		 (coordinates.z() == 0 && (boundaryCondition & 32)) or
+		 (coordinates.z() == mesh.getDimensions().y() - 1  && (boundaryCondition & 16)))
+
+		)
+	{
+		return 0.0;
+	}
+
+
+	//-----------------------------------
+
+	RealType signui;
+	signui = sign(u[cellIndex], this->epsilon);
+
+
+	RealType xb = u[cellIndex];
+	RealType xf = -u[cellIndex];
+	RealType yb = u[cellIndex];
+	RealType yf = -u[cellIndex];
+	RealType zb = u[cellIndex];
+	RealType zf = -u[cellIndex];
+	RealType a,b,c,d;
+
+
+	   if(coordinates.x() == mesh.getDimensions().x() - 1)
+		   xf += u[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+	   else
+		   xf += u[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+	   else
+		   xb -= u[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+	   else
+		   yf += u[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+	   else
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+
+
+	   if(coordinates.z() == mesh.getDimensions().z() - 1)
+		   zf += u[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+	   else
+		   zf += u[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+
+	   if(coordinates.z() == 0)
+		   zb -= u[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+	   else
+		   zb -= u[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart(xf);
+
+		   xb = positivePart(xb);
+
+		   yf = negativePart(yf);
+
+		   yb = positivePart(yb);
+
+		   zf = negativePart(zf);
+
+		   zb = positivePart(zb);
+
+	   }
+	   else if(signui < 0.0)
+	   {
+
+		   xb = negativePart(xb);
+
+		   xf = positivePart(xf);
+
+		   yb = negativePart(yb);
+
+		   yf = positivePart(yf);
+
+		   zb = negativePart(zb);
+
+		   zf = positivePart(zf);
+	   }
+
+
+	   if(xb - xf > 0.0)
+		   a = xb;
+	   else
+		   a = xf;
+
+	   if(yb - yf > 0.0)
+		   b = yb;
+	   else
+		   b = yf;
+
+	   if(zb - zf > 0.0)
+		   c = zb;
+	   else
+		   c = zf;
+
+	   d = ( 1.0 - sqrt(a*a + b*b + c*c)*ihx );
+
+//	   d = 1.0 - sqrt(xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb)*ihx; /*upwind*/
+
+	   if(sign(d) > 0.0 )
+		   return sign(u[cellIndex])*d;
+	   else
+		   return signui*d;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+
+#ifdef HAVE_CUDA
+__device__
+#endif
+Real parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real* u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	          	  	  	  	  	  	  	  	  	  	                     const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 ) const
+{
+	RealType signui;
+		signui = sign(u[cellIndex], this->epsilon);
+
+
+		RealType xb = u[cellIndex];
+		RealType xf = -u[cellIndex];
+		RealType yb = u[cellIndex];
+		RealType yf = -u[cellIndex];
+		RealType zb = u[cellIndex];
+		RealType zf = -u[cellIndex];
+		RealType a,b,c,d;
+
+
+		   if(coordinates.x() == mesh.getDimensions().x() - 1)
+			   xf += u[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+		   else
+			   xf += u[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+
+		   if(coordinates.x() == 0)
+			   xb -= u[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+		   else
+			   xb -= u[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+
+		   if(coordinates.y() == mesh.getDimensions().y() - 1)
+			   yf += u[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+		   else
+			   yf += u[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+
+		   if(coordinates.y() == 0)
+			   yb -= u[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+		   else
+			   yb -= u[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+
+
+		   if(coordinates.z() == mesh.getDimensions().z() - 1)
+			   zf += u[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+		   else
+			   zf += u[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+
+		   if(coordinates.z() == 0)
+			   zb -= u[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+		   else
+			   zb -= u[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+
+		   if(signui > 0.0)
+		   {
+			   xf = negativePart(xf);
+
+			   xb = positivePart(xb);
+
+			   yf = negativePart(yf);
+
+			   yb = positivePart(yb);
+
+			   zf = negativePart(zf);
+
+			   zb = positivePart(zb);
+
+		   }
+		   else if(signui < 0.0)
+		   {
+
+			   xb = negativePart(xb);
+
+			   xf = positivePart(xf);
+
+			   yb = negativePart(yb);
+
+			   yf = positivePart(yf);
+
+			   zb = negativePart(zb);
+
+			   zf = positivePart(zf);
+		   }
+
+
+		   if(xb - xf > 0.0)
+			   a = xb;
+		   else
+			   a = xf;
+
+		   if(yb - yf > 0.0)
+			   b = yb;
+		   else
+			   b = yf;
+
+		   if(zb - zf > 0.0)
+			   c = zb;
+		   else
+			   c = zf;
+
+		   d = ( 1.0 - sqrt(a*a + b*b + c*c)*ihx );
+
+	//	   d = 1.0 - sqrt(xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb)*ihx; /*upwind*/
+
+		   if(sign(d) > 0.0 )
+			   return sign(u[cellIndex])*d;
+		   else
+			   return signui*d;
+}
+
+
+#endif /* PARALLELGODUNOVEIKONAL3D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..deeff7c08850c41319ea2bfbfd55fa8d83cb9a9d
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h
@@ -0,0 +1,270 @@
+/***************************************************************************
+                          parallelGodunovMap.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVMAP_H_
+#define PARALLELGODUNOVMAP_H_
+
+#include <matrices/tnlCSRMatrix.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/tnlSolverMonitor.h>
+#include <core/tnlLogger.h>
+#include <TNL/Containers/Vector.h>
+#include <core/mfilename.h>
+#include <mesh/tnlGrid.h>
+#include <core/tnlCuda.h>
+#include <mesh/grids/tnlGridEntity.h>
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class parallelGodunovMapScheme
+{
+};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovMapScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 1, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	RealType sign(const RealType x, const RealType eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+	MeshType originalMesh;
+
+	DofVectorType dofVector;
+
+	RealType h;
+
+
+
+
+};
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType sign(const RealType x, const Real eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+                   const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities,
+                   const Vector& map) const;
+
+ #ifdef HAVE_CUDA
+    __device__
+ #endif
+    Real getValueDev( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const RealType* u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+                   const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities,
+  	  	  	       const RealType* map) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+ 	MeshType originalMesh;
+
+    DofVectorType dofVector;
+
+    RealType hx, ihx;
+    RealType hy, ihy;
+
+
+
+
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class parallelGodunovMapScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+	static String getType();
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType positivePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType negativePart(const RealType arg) const;
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    RealType sign(const RealType x, const Real eps) const;
+
+    template< typename Vector >
+ #ifdef HAVE_CUDA
+    __device__ __host__
+ #endif
+    Real getValue( const MeshType& mesh,
+                   const IndexType cellIndex,
+                   const CoordinatesType& coordinates,
+                   const Vector& u,
+                   const RealType& time,
+                   const IndexType boundaryCondition,
+  	  	  	       const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities  ) const;
+
+#ifdef HAVE_CUDA
+   __device__
+#endif
+   Real getValueDev( const MeshType& mesh,
+                  const IndexType cellIndex,
+                  const CoordinatesType& coordinates,
+                  const RealType* u,
+                  const RealType& time,
+                  const IndexType boundaryCondition,
+ 	  	  	      const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities) const;
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+    bool init( const Config::ParameterContainer& parameters );
+
+   RealType epsilon;
+
+protected:
+
+ 	MeshType originalMesh;
+
+    DofVectorType dofVector;
+
+    RealType hx, ihx;
+    RealType hy, ihy;
+    RealType hz, ihz;
+
+};
+
+
+
+//#include <operators/godunov-eikonal/parallelGodunovMap1D_impl.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovMap2D_impl.h>
+//#include <operators/godunov-eikonal/parallelGodunovMap3D_impl.h>
+
+
+#endif /* PARALLELGODUNOVMAP_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b3117cf25a8d039002db1c6ba7328ea0870d492
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h
@@ -0,0 +1,391 @@
+/***************************************************************************
+                          parallelGodunovMap2D_impl.h  -  description
+                             -------------------
+    begin                : Dec 1 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 PARALLELGODUNOVMAP2D_IMPL_H_
+#define PARALLELGODUNOVMAP2D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real  parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return -arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	if (x < -eps)
+		return (-1.0);
+
+	if ( x == 0.0)
+		return 0.0;
+
+	return sin(/*(M_PI*x)/(2.0*eps)	*/(M_PI/2.0)*(x/eps));
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+bool parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   //MeshType originalMesh;
+	   if( ! originalMesh.load( meshFile ) )
+	   {
+		   //cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+
+
+	   hx = originalMesh.template getSpaceStepsProducts< 1, 0 >();
+	   ihx = 1.0/hx;
+	   hy = originalMesh.template getSpaceStepsProducts< 0, 1 >();
+	   ihy = 1.0/hy;
+
+	   this->epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   this->epsilon *=sqrt( hx*hx + hy*hy );
+
+//	   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+String parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+   return String( "parallelGodunovMapScheme< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& map) const
+{
+
+
+	if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or
+		 (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or
+		 (coordinates.y() == 0 && (boundaryCondition & 8)) or
+		 (coordinates.y() == mesh.getDimensions().y() - 1  && (boundaryCondition & 1)))
+		 /*and
+		 !(		 (coordinates.y() == 0 or coordinates.y() == mesh.getDimensions().y() - 1)
+				 and
+				 ( coordinates.x() == 0 or coordinates.x() == mesh.getDimensions().x() - 1)
+		  )*/
+		)
+	{
+		return 0.0;
+	}
+
+
+	RealType signui;
+//	if(boundaryCondition == 0)
+		signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon);
+//	else
+//		signui = sign(u[cellIndex]);
+
+	RealType value;
+//	if(map[cellIndex] == 0.0)
+//	{
+////		value = INT_MAX;
+//		u[cellIndex] = sign(u[cellIndex])*INT_MAX;
+//		return 0.0;
+//	}
+//	else
+		value = 1.0/ map[cellIndex];
+
+
+	RealType xb = u[cellIndex];
+	RealType xf = -u[cellIndex];
+	RealType yb = u[cellIndex];
+	RealType yf = -u[cellIndex];
+	RealType a,b,c;
+
+
+	   if(coordinates.x() == mesh.getDimensions().x() - 1)
+		   xf += u[neighborEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighborEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighborEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighborEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighborEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart(xf);
+
+		   xb = positivePart(xb);
+
+		   yf = negativePart(yf);
+
+		   yb = positivePart(yb);
+
+	   }
+	   else if(signui < 0.0)
+	   {
+
+		   xb = negativePart(xb);
+
+		   xf = positivePart(xf);
+
+		   yb = negativePart(yb);
+
+		   yf = positivePart(yf);
+	   }
+
+	   /*if(boundaryCondition &1)
+		   yb = 0.0;
+	   else
+		   yf = 0.0;
+
+	   if(boundaryCondition & 2)
+		   xb = 0.0;
+	   else
+		   xf = 0.0;*/
+
+	   if(xb - xf > 0.0)
+		   a = xb;
+	   else
+		   a = xf;
+
+	   if(yb - yf > 0.0)
+		   b = yb;
+	   else
+		   b = yf;
+
+	   c =(value - sqrt(a*a+b*b)*ihx );
+
+	   if(c > 0.0 )
+		   return sign(u[cellIndex])*c;
+	   else
+
+	   return signui*c;
+
+}
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+
+#ifdef HAVE_CUDA
+__device__
+#endif
+Real parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real* u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType boundaryCondition,
+          	  	  	  	  	  	  	  	  	  	                     const tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities,
+          	  	  	  	  	  	  	  	  	  	                     const Real* map) const
+{
+//	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x;
+
+	RealType signui;
+	if(boundaryCondition == 0)
+		signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon);
+	else
+		signui = sign(u[cellIndex]);
+
+//	RealType value;
+//	if(map[cellIndex] == 0.0)
+//	{
+////		value = INT_MAX;
+//		u[cellIndex] = sign(u[cellIndex])*INT_MAX;
+//		return 0.0;
+//	}
+//	else
+	RealType value = /*1.0/*/ map[cellIndex];
+
+
+	RealType xb = u[cellIndex];
+	RealType xf = -u[cellIndex];
+	RealType yb = u[cellIndex];
+	RealType yf = -u[cellIndex];
+	RealType a,b,c;
+
+
+	   if(coordinates.x() == mesh.getDimensions().x() - 1)
+		   xf += u[neighborEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighborEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighborEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighborEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighborEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighborEntities.template getEntityIndex< 0,  -1 >()];
+
+
+	   if(signui > 0.0)
+	   {
+		   xf = negativePart(xf);
+
+		   xb = positivePart(xb);
+
+		   yf = negativePart(yf);
+
+		   yb = positivePart(yb);
+
+	   }
+	   else if(signui < 0.0)
+	   {
+
+		   xb = negativePart(xb);
+
+		   xf = positivePart(xf);
+
+		   yb = negativePart(yb);
+
+		   yf = positivePart(yf);
+	   }
+
+//	   if(boundaryCondition &1)
+//		   yb = 0.0;
+//	   else
+//		   yf = 0.0;
+//
+//	   if(boundaryCondition & 2)
+//		   xb = 0.0;
+//	   else
+//		   xf = 0.0;
+
+	   if(xb > xf)
+		   a = xb;
+	   else
+		   a = xf;
+
+	   if(yb > yf)
+		   b = yb;
+	   else
+		   b = yf;
+
+	   c = (value - sqrt(a*a+b*b)*ihx );
+
+//	   if(c > 0.0 )
+//		   return sign(u[cellIndex])*c;
+//	   else
+		   return signui*c;
+}
+
+
+#endif /* PARALLELGODUNOVMAP2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..98b3eefe79e290a43e25867cf4e2c7cad9a1a419
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt
@@ -0,0 +1,17 @@
+set( headers godunov1D_impl.h
+             godunov2D_impl.h
+             godunov3D_impl.h)
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov )
+
+if( BUILD_CUDA)
+      set( tnl_implementation_operators_godunov_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_implementation_operators_godunov_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Godunov/ )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f902ad7d8dc81273a7e0067f29c459a4bbd1dfc
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+                          godunov1D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 GODUNOV1D_IMPL_H_
+#define GODUNOV1D_IMPL_H_
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real  godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if(eps == 0.0)
+		return 0.0;
+
+	return sin( ( M_PI * x ) / (2 * eps) );
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+bool godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters )
+{
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   h = originalMesh.getSpaceSteps().x();
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=h;
+
+	   f.setup( parameters );
+
+	   /*dofVector. setSize( this->mesh.getDofs() );*/
+
+	   return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+String godunovScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType()
+{
+   return String( "godunovScheme< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+
+	RealType nabla, xb, xf, fi;
+
+	fi = f.getValue(mesh.getCellCenter( coordinates ),time);
+
+	   if(fi > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return -fi*( nabla);
+	   }
+	   else if (fi < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb );
+
+		   return -fi*( nabla);
+	   }
+	   else
+	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* GODUNOV1D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdd7e671630ec4c2eb40230f80b779c1f5058f89
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h
@@ -0,0 +1,192 @@
+/***************************************************************************
+                          godunov2D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 GODUNOV2D_IMPL_H_
+#define GODUNOV2D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function >:: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real  godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if ( eps == 0.0)
+		return 0.0;
+
+	return sin((M_PI*x)/(2.0*eps));
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+bool godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters )
+{
+
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+	   hx = originalMesh.getSpaceSteps().x();
+	   hy = originalMesh.getSpaceSteps().y();
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=sqrt( hx*hx + hy*hy );
+
+	   f.setup( parameters );
+
+//	   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+String godunovScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType()
+{
+   return String( "tnlLinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+
+
+	RealType nabla, xb, xf, yb, yf, fi;
+
+	fi = f.getValue(mesh.getCellCenter( coordinates ),time);
+
+	   if(fi > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yf = 0.0;
+		   else
+			   yb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+
+		   return -1.0*fi*( nabla);
+	   }
+	   else if (fi < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yb = 0.0;
+		   else
+			   yf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb );
+
+		   return -1.0*fi*( nabla);
+	   }
+	   else
+	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* GODUNOV2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d25f354bc0a4cc448166ad44d3400f16132682f9
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h
@@ -0,0 +1,204 @@
+/***************************************************************************
+                          godunov3D_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 GODUNOV3D_IMPL_H_
+#define GODUNOV3D_IMPL_H_
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: positivePart(const Real arg) const
+{
+	if(arg > 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real  godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const
+{
+	if(arg < 0.0)
+		return arg;
+	return 0.0;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+Real godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const
+{
+	if(x > eps)
+		return 1.0;
+	else if (x < -eps)
+		return (-1.0);
+
+	if ( eps == 0.0)
+		return 0.0;
+
+	return sin((M_PI*x)/(2.0*eps));
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+bool godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters )
+{
+	   const String& meshFile = parameters.getParameter< String >( "mesh" );
+	   if( ! this->originalMesh.load( meshFile ) )
+	   {
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	   }
+
+
+	   hx = originalMesh.getSpaceSteps().x();
+	   hy = originalMesh.getSpaceSteps().y();
+	   hz = originalMesh.getSpaceSteps().z();
+
+	   epsilon = parameters. getParameter< double >( "epsilon" );
+
+	   if(epsilon != 0.0)
+		   epsilon *=sqrt( hx*hx + hy*hy +hz*hz );
+
+	   f.setup( parameters );
+
+	//   dofVector. setSize( this->mesh.getDofs() );
+
+	   return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+String godunovScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType()
+{
+   return String( "tnlLinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+		  typename Function >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real godunovScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const IndexType cellIndex,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const CoordinatesType& coordinates,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Vector& u,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 const Real& time ) const
+{
+
+	RealType nabla, xb, xf, yb, yf, zb, zf, fi;
+
+	fi = f.getValue(mesh.getCellCenter( coordinates ),time);
+
+	   if(fi > 0.0)
+	   {
+		   xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+		   zf = negativePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz);
+		   zb = positivePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz);
+
+		   if(xb + xf > 0.0)
+			   xf = 0.0;
+		   else
+			   xb = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yf = 0.0;
+		   else
+			   yb = 0.0;
+
+		   if(zb + zf > 0.0)
+			   zf = 0.0;
+		   else
+			   zb = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb );
+
+		   return -fi*( nabla);
+	   }
+	   else if (fi < 0.0)
+	   {
+		   xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx);
+		   xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx);
+		   yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy);
+		   yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy);
+		   zf = positivePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz);
+		   zb = negativePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz);
+
+		   if(xb + xf > 0.0)
+			   xb = 0.0;
+		   else
+			   xf = 0.0;
+
+		   if(yb + yf > 0.0)
+			   yb = 0.0;
+		   else
+			   yf = 0.0;
+
+		   if(zb + zf > 0.0)
+			   zb = 0.0;
+		   else
+			   zf = 0.0;
+
+		   nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb );
+
+		   return -fi*( nabla);
+	   }
+	   else
+	   {
+		   return 0.0;
+	   }
+
+}
+
+
+#endif /* GODUNOV3D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..4be92ef39ea02faa1ca03d85fbf214b20a81ab60
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h
@@ -0,0 +1,66 @@
+/* 
+ * File:   tnlEikonalOperator.h
+ * Author: oberhuber
+ *
+ * Created on July 11, 2016, 6:33 PM
+ */
+
+#pragma once
+
+#include <functions/tnlConstantFunction.h>
+#include <functions/tnlFunctionAdapter.h>
+
+template< typename GradientNormOperator,
+          typename Anisotropy = 
+            tnlConstantFunction< GradientNormOperator::MeshType::getMeshDimension(),
+                                 typename GradientNormOperator::MeshType::RealType > >
+class tnlEikonalOperator
+   : public tnlOperator< typename GradientNormOperator::MeshType, MeshDomain >
+{
+      public:
+         
+         typedef typename GradientNormOperator::MeshType MeshType;
+         typedef typename MeshType::RealType RealType;
+         typedef typename MeshType::DeviceType DeviceType;
+         typedef typename MeshType::IndexType IndexType;      
+         typedef GradientNormOperator GradientNormOperatorType;
+         typedef Anisotropy AnisotropyType;
+         //typedef tnlExactLinearDiffusion< 1 > ExactOperatorType;
+      
+         static const int Dimensions = MeshType::meshDimensions;
+      
+         static constexpr int getDimension() { return Dimensions; }
+      
+         static String getType();
+         
+         AnisotropyType& getAnisotropy() { return this->anisotropy; };
+         
+         const AnisotropyType& getAnisotropy() const { return this->anisotropy; };
+         
+         const RealType getSmoothing() const { return this->smoothing; };
+         
+         void setSmoothing( const RealType& smoothing ) { this->smoothing = smoothing; };
+         
+         template< typename PreimageFunction,
+                   typename MeshEntity >
+         __cuda_callable__
+         RealType operator()( const PreimageFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time = 0.0 ) const
+         {
+            const RealType signU = sign( u( entity ), smoothing * entity.getMesh().getSmallestSpaceStep() );
+            const RealType f = tnlFunctionAdapter< MeshType, AnisotropyType >::getValue( anisotropy, entity, 0.0 );
+            return signU * ( f - gradientNorm( u, entity, signU ) );
+         };
+
+      protected:
+         
+         GradientNormOperatorType gradientNorm;
+         
+         AnisotropyType anisotropy;
+
+         RealType smoothing;
+         
+};
+ 
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h
new file mode 100644
index 0000000000000000000000000000000000000000..7467f66715e6dcc5fcf9a04ac0ecd66d1f026a11
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h
@@ -0,0 +1,202 @@
+/***************************************************************************
+                          upwindEikonal.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlFunctions.h>
+
+template< typename Mesh,
+		    typename Real,
+		    typename Index >
+class upwindEikonalScheme
+{
+};
+
+/****
+ * 1D scheme
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class upwindEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+      static String getType();
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& f ) const
+      {
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1 >();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
+
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex< 1 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1 >() ];
+
+         if( f > 0.0 )
+         {
+            const RealType& xf = negativePart( ( u_e - u_c ) * hx_inv );
+            const RealType& xb = positivePart( ( u_c - u_w ) * hx_inv );
+            return sqrt( xf * xf + xb * xb );
+         }
+         else if( f < 0.0 )
+         {
+            const RealType& xf = negativePart( ( u_c - u_w ) * hx_inv );
+            const RealType& xb = positivePart( ( u_e - u_c ) * hx_inv );
+            return sqrt( xf * xf + xb * xb );
+         }
+         else
+         {
+            return 0.0;
+         }
+      };
+};
+
+/****
+ * 2D scheme
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class upwindEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+      static String getType();
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const PreimageFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& f ) const
+      {   
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
+         const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts<  0, -1 >();
+
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();   
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex<  1,  0 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1,  0 >() ];
+         const RealType& u_n = u[ neighborEntities.template getEntityIndex<  0,  1 >() ];
+         const RealType& u_s = u[ neighborEntities.template getEntityIndex<  0, -1 >() ];
+         if( f > 0.0 )
+         {
+            const RealType xf = negativePart( ( u_e - u_c ) * hx_inv );
+            const RealType xb = positivePart( ( u_c - u_w ) * hx_inv );
+            const RealType yf = negativePart( ( u_n - u_c ) * hy_inv );
+            const RealType yb = positivePart( ( u_c - u_s ) * hy_inv );
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb );
+         }
+         else if( f < 0.0 )
+         {
+            const RealType xf = positivePart( ( u_e - u_c ) * hx_inv );
+            const RealType xb = negativePart( ( u_c - u_w ) * hx_inv );
+            const RealType yf = positivePart( ( u_n - u_c ) * hy_inv );
+            const RealType yb = negativePart( ( u_c - u_s ) * hy_inv );
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb );
+         }
+         else
+            return 0.0;
+      }
+};
+
+/****
+ * 3D scheme
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class upwindEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+   public:
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+      static String getType();
+
+      template< typename PreimageFunction, typename MeshEntity >
+      __cuda_callable__
+       Real operator()( const PreimageFunction& u,
+                        const MeshEntity& entity,
+                        const RealType& f ) const
+      {
+         const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >();
+         const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >();
+         const RealType& hz_inv = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >();
+
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ];
+         const RealType& u_w = u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ];
+         const RealType& u_n = u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ];
+         const RealType& u_s = u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ];
+         const RealType& u_t = u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ];
+         const RealType& u_b = u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ];
+
+         if( f > 0.0 )
+         {
+            const RealType xf = negativePart( ( u_e - u_c ) * hx_inv );
+            const RealType xb = positivePart( ( u_c - u_w ) * hx_inv );
+            const RealType yf = negativePart( ( u_n - u_c ) * hy_inv );
+            const RealType yb = positivePart( ( u_c - u_s ) * hy_inv );
+            const RealType zf = negativePart( ( u_t - u_c ) * hz_inv );
+            const RealType zb = positivePart( ( u_c - u_b ) * hz_inv );
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb );
+         }
+         else if( f < 0.0 )
+         {
+            const RealType xf = positivePart( ( u_e - u_c ) * hx_inv );
+            const RealType xb = negativePart( ( u_c - u_w ) * hx_inv );
+            const RealType yf = positivePart( ( u_n - u_c ) * hy_inv );
+            const RealType yb = negativePart( ( u_c - u_s ) * hy_inv );
+            const RealType zf = positivePart( ( u_t - u_c ) * hz_inv );
+            const RealType zb = negativePart( ( u_c - u_b ) * hz_inv );
+            return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb );
+         }
+         else
+            return 0.0;
+      };
+};
\ No newline at end of file
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b4ec5170b50f7b9bfdf6b81f261f396c0c59d624
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_SUBDIRECTORY( hamilton-jacobi )
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..73cc05e2646fd6f5ad77227a73722d981580f7c6
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt
@@ -0,0 +1,22 @@
+set( tnl_fast_sweeping_map_SOURCES
+#     MainBuildConfig.h
+#     tnlFastSweepingMap2D_impl.h
+#     tnlFastSweepingMap.h
+#     fastSweepingMapConfig.h 
+     main.cpp)
+
+
+IF(  BUILD_CUDA ) 
+	CUDA_ADD_EXECUTABLE(fast-sweeping-map${debugExt} main.cu)
+ELSE(  BUILD_CUDA )                
+	ADD_EXECUTABLE(fast-sweeping-map${debugExt} main.cpp)
+ENDIF( BUILD_CUDA )
+target_link_libraries (fast-sweeping-map${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS fast-sweeping-map${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+#INSTALL( FILES ${tnl_fast_sweeping_map_SOURCES}
+#         DESTINATION share/tnl-${tnlVersion}/examples/fast-sweeping-map )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..9251deca876e821dace59682ca1a151555095c69
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+                          fastSweepingConfig.h  -  description
+                             -------------------
+    begin                : Oct 15, 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 FASTSWEEPINGCONFIG_H_
+#define FASTSWEEPINGCONFIG_H_
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class fastSweepingMapConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Parallel Eikonal solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" );
+         config.addRequiredEntry        < String > ( "initial-condition", "Initial condition for solver");
+         config.addRequiredEntry        < int > ( "dim", "Dimension of problem.");
+         config.addEntry       < String > ( "mesh", "Name of mesh.", "mesh.tnl" );
+         config.addEntry       < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" );
+         config.addRequiredEntry        < String > ( "map", "Gradient map for solver");
+      }
+};
+
+#endif /* FASTSWEEPINGCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..813e99c72cd6de9b597c10a943ab666220453018
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+                          main.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "MainBuildConfig.h"
+	//for HOST versions:
+#include "tnlFastSweepingMap.h"
+	//for DEVICE versions:
+//#include "tnlFastSweepingMap_CUDA.h"
+#include "fastSweepingMapConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+
+#include <mesh/tnlGrid.h>
+#include <core/tnlDevice.h>
+#include <time.h>
+#include <ctime>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+	time_t start;
+	time_t stop;
+	time(&start);
+	std::clock_t start2= std::clock();
+   Config::ParameterContainer parameters;
+   tnlConfigDescription configDescription;
+   fastSweepingMapConfig< BuildConfig >::configSetup( configDescription );
+
+   if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
+      return false;
+
+   const int& dim = parameters.getParameter< int >( "dim" );
+
+   if(dim == 2)
+   {
+		tnlFastSweepingMap<tnlGrid<2,double,TNL::Devices::Host, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		TNL_CHECK_CUDA_DEVICE;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+//   else if(dim == 3)
+//   {
+//		tnlFastSweepingMap<tnlGrid<3,double,TNL::Devices::Host, int>, double, int> solver;
+//		if(!solver.init(parameters))
+//	   {
+//			cerr << "Solver failed to initialize." << endl;
+//			return EXIT_FAILURE;
+//	   }
+//		TNL_CHECK_CUDA_DEVICE;
+//	   cout << "-------------------------------------------------------------" << endl;
+//	   cout << "Starting solver..." << endl;
+//	   solver.run();
+//   }
+   else
+   {
+	   cerr << "Unsupported number of dimensions: " << dim << "!" << endl;
+	   return EXIT_FAILURE;
+   }
+
+
+   time(&stop);
+   cout << "Solver stopped..." << endl;
+   cout << endl;
+   cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..c568329ba2aa5fdb8fed303d43b25e73f210c014
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h
@@ -0,0 +1,188 @@
+/***************************************************************************
+                          tnlFastSweepingMap.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING_H_
+#define TNLFASTSWEEPING_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+#ifdef HAVE_OPENMP
+#include <omp.h>
+#endif
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlFastSweepingMap
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+	tnlFastSweepingMap();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+
+	void setupSquare1000(Index i, Index j);
+	void setupSquare1100(Index i, Index j);
+	void setupSquare1010(Index i, Index j);
+	void setupSquare1001(Index i, Index j);
+	void setupSquare1110(Index i, Index j);
+	void setupSquare1101(Index i, Index j);
+	void setupSquare1011(Index i, Index j);
+	void setupSquare1111(Index i, Index j);
+	void setupSquare0000(Index i, Index j);
+	void setupSquare0100(Index i, Index j);
+	void setupSquare0010(Index i, Index j);
+	void setupSquare0001(Index i, Index j);
+	void setupSquare0110(Index i, Index j);
+	void setupSquare0101(Index i, Index j);
+	void setupSquare0011(Index i, Index j);
+	void setupSquare0111(Index i, Index j);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+	int something_changed;
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data,map;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity;
+
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlFastSweepingMap();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j, const Index k);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity;
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+	//for single core version use this implementation:
+#include "tnlFastSweepingMap2D_impl.h"
+	//for parallel version use this one instead:
+// #include "tnlFastSweepingMap2D_openMP_impl.h"
+
+//											#include "tnlFastSweepingMap3D_impl.h"
+
+#endif /* TNLFASTSWEEPING_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b865bef001413f10d2862e0c16675e5c33309470
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h
@@ -0,0 +1,1051 @@
+/***************************************************************************
+                          tnlFastSweepingMap2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweepingMap.h"
+
+#define MAP_SOLVER_MAX_VALUE 3
+
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweepingMap< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweepingMap()
+:dofVector(Mesh)
+{
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	const String& mapFile = parameters.getParameter <String>("map");
+	if(! this->map.load( mapFile ))
+		cout << "Failed to load map file : " << mapFile << endl;
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	//Entity.refresh();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(map_cuda), this->map.getSize()*sizeof(double));
+	cudaMemcpy(map_cuda, this->map.getData(), this->map.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(changed), sizeof(int));
+	//counter == 0 --> setting changed to 0
+	cudaMemcpy(changed, &counter, sizeof(int), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(1, 1024);
+	dim3 numBlocks(4,1);
+
+	int run = 1;
+	int zero = 0;
+	int cntr = 0;
+
+	while(run != 0)
+	{
+		cudaMemcpy(this->changed, &zero, sizeof(int), cudaMemcpyHostToDevice);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0, this->changed);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		cudaMemcpy(&run, this->changed,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		cntr++;
+		cout << "Finished set of sweeps #" << cntr << "           " << run << endl;
+	}
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	//data.setLike(dofVector.getData());
+	//cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	//data.save("u-00001.tnl");
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index* something_changed)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+
+	if(map_cuda[Entity.getIndex()] != 0.0)
+	{
+		tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real im = abs(1.0/map_cuda[Entity.getIndex()]);
+		Real a,b, tmp;
+
+		if( i == 0 )
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 )
+			a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 )
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 )
+			b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+		}
+
+
+		if(abs(a-b) >= im*h)
+			tmp = fabsMin(a,b) + sign(value)*im*h;
+		else
+			tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * im * h * im * h - (a - b) * (a - b) ) );
+
+	//	cudaDofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+		atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp);
+
+		if(abs(value)-abs(tmp) > 0.0)
+			atomicMax(something_changed,1);
+	}
+	else
+	{
+		atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), MAP_SOLVER_MAX_VALUE);
+	}
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int i = threadIdx.x + blockDim.x*blockIdx.x;
+	int j = blockDim.y*blockIdx.y + threadIdx.y;
+
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	int gid = Entity.getIndex();
+
+	cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]);
+
+	if(abs(cudaDofVector[gid]) < 1.01*h)
+	{
+		cudaDofVector2[gid] = cudaDofVector[gid];
+		if(map_cuda[gid] != 0.0)
+			cudaDofVector2[gid] /=map_cuda[gid];
+	}
+
+
+
+
+
+//	if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() )
+//	{
+//		if(cudaDofVector[Entity.getIndex()] > 0)
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0001(i,j);
+//					else
+//						setupSquare0000(i,j);
+//				}
+//			}
+//		}
+//
+//	}
+
+	return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	//Real fy = abs(y);
+
+	//Real tmpMin = Min(fx,abs(y));
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i, int* changed)
+{
+
+	__shared__ int something_changed;
+	if(threadIdx.x+threadIdx.y == 0)
+		something_changed = 0;
+
+	int gx = 0;
+	int gy = threadIdx.y;
+	//if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+	//	return;
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	//int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	//int id1 = gx+gy;
+	//int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+	__syncthreads();
+	if(blockIdx.x==0)
+	{
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,&something_changed);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,&something_changed);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,&something_changed);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,&something_changed);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+
+
+	if(threadIdx.x+threadIdx.y == 0)
+		atomicMax(changed, something_changed);
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+
+
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f4d6f86c6f2db94e7ed8ac728cb5334216c32a8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h
@@ -0,0 +1,823 @@
+/***************************************************************************
+                          tnlFastSweepingMap2D_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+
+#define MAP_SOLVER_MAX_VALUE 3
+
+
+#include "tnlFastSweepingMap.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweepingMap< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweepingMap()
+:Entity(Mesh),
+ dofVector(Mesh),
+ dofVector2(Mesh)
+{
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+	dofVector2.load(initialCondition);
+
+	const String& mapFile = parameters.getParameter <String>("map");
+	if(! this->map.load( mapFile ))
+		cout << "Failed to load map file : " << mapFile << endl;
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	Entity.refresh();
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+	cout << "a" << endl;
+
+	something_changed = 1;
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++)
+	{
+		dofVector2[i]=INT_MAX*sign(dofVector[i]);
+
+		if(abs(dofVector[i]) < 1.01*h)
+		{
+			dofVector2[i] = dofVector[i];
+			if(map[i] != 0.0)
+				dofVector2[i] /= map[i];
+		}
+	}
+
+//	for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++)
+//			{
+//			this->Entity.setCoordinates(CoordinatesType(i,j));
+//			this->Entity.refresh();
+//			neighborEntities.refresh(Mesh,Entity.getIndex());
+//
+//				if(dofVector[this->Entity.getIndex()] > 0)
+//				{
+//					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//					{
+//						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1111(i,j);
+//							else
+//								setupSquare1110(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1101(i,j);
+//							else
+//								setupSquare1100(i,j);
+//						}
+//					}
+//					else
+//					{
+//						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1011(i,j);
+//							else
+//								setupSquare1010(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1001(i,j);
+//							else
+//								setupSquare1000(i,j);
+//						}
+//					}
+//				}
+//				else
+//				{
+//					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+//					{
+//						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0111(i,j);
+//							else
+//								setupSquare0110(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0101(i,j);
+//							else
+//								setupSquare0100(i,j);
+//						}
+//					}
+//					else
+//					{
+//						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0011(i,j);
+//							else
+//								setupSquare0010(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0001(i,j);
+//							else
+//								setupSquare0000(i,j);
+//						}
+//					}
+//				}
+//
+//			}
+//	}
+	cout << "a" << endl;
+
+	//data.setLike(dofVector2.getData());
+	//data=dofVector2.getData();
+	//cout << data.getType() << endl;
+	dofVector2.save("u-00000.tnl");
+	//dofVector2.getData().save("u-00000.tnl");
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+	int cntr = 0;
+	while(something_changed != 0)
+	{
+		something_changed = 0;
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j);
+			}
+		}
+
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j);
+			}
+		}
+
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j);
+			}
+		}
+
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j);
+			}
+		}
+
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+		cntr++;
+		cout << "Finished set of sweeps #" << cntr << "           " << something_changed << endl;
+	}
+
+
+
+	dofVector2.save("u-00001.tnl");
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	if(map[Entity.getIndex()] != 0.0)
+	{
+		tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+		Real value = dofVector2[Entity.getIndex()];
+		Real im = abs(1.0/map[Entity.getIndex()]);
+		Real a,b, tmp;
+
+		if( i == 0 )
+			a = dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 )
+			a = dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+					 dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 )
+			b = dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 )
+			b = dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+					 dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+		}
+
+
+		if(fabs(a-b) >= im*h)
+			tmp = fabsMin(a,b) + sign(value)*im*h;
+		else
+			tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * im * h * im * h - (a - b) * (a - b) ) );
+
+		if(abs(value)-abs(tmp) > 0.0)
+			something_changed = 1;
+
+		dofVector2[Entity.getIndex()] = fabsMin(value, tmp);
+
+	}
+	else
+	{
+		dofVector2[Entity.getIndex()] = MAP_SOLVER_MAX_VALUE;
+	}
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h
new file mode 100644
index 0000000000000000000000000000000000000000..a23057e78c745e74467db4c4190d6f217024bc5a
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h
@@ -0,0 +1,196 @@
+/***************************************************************************
+                          tnlFastSweepingMap_CUDA.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING_H_
+#define TNLFASTSWEEPING_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+
+#include <functions/tnlMeshFunction.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlFastSweepingMap
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlFastSweepingMap();
+
+	__host__ static String getType();
+	__host__ bool init( const Config::ParameterContainer& parameters );
+	__host__ bool run();
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid();
+	__device__ void updateValue(const Index i, const Index j, Index* something_changed);
+	__device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	double* map_cuda;
+	int counter;
+	int* changed;
+	__device__ void setupSquare1000(Index i, Index j);
+	__device__ void setupSquare1100(Index i, Index j);
+	__device__ void setupSquare1010(Index i, Index j);
+	__device__ void setupSquare1001(Index i, Index j);
+	__device__ void setupSquare1110(Index i, Index j);
+	__device__ void setupSquare1101(Index i, Index j);
+	__device__ void setupSquare1011(Index i, Index j);
+	__device__ void setupSquare1111(Index i, Index j);
+	__device__ void setupSquare0000(Index i, Index j);
+	__device__ void setupSquare0100(Index i, Index j);
+	__device__ void setupSquare0010(Index i, Index j);
+	__device__ void setupSquare0001(Index i, Index j);
+	__device__ void setupSquare0110(Index i, Index j);
+	__device__ void setupSquare0101(Index i, Index j);
+	__device__ void setupSquare0011(Index i, Index j);
+	__device__ void setupSquare0111(Index i, Index j);
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data, map;
+
+
+	RealType h;
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+
+	__host__ static String getType();
+	__host__ bool init( const Config::ParameterContainer& parameters );
+	__host__ bool run();
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid(int i, int j, int k);
+	__device__ void updateValue(const Index i, const Index j, const Index k);
+	__device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	int counter;
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data;
+
+	RealType h;
+
+
+};
+
+
+
+
+
+
+
+#ifdef HAVE_CUDA
+//template<int sweep_t>
+__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i, int* changed);
+//__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+//__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver);
+#endif
+
+/*various implementtions.... choose one*/
+//#include "tnlFastSweepingMap2D_CUDA_impl.h"
+//#include "tnlFastSweepingMap2D_CUDA_v2_impl.h"
+//#include "tnlFastSweepingMap2D_CUDA_v3_impl.h"
+#include "tnlFastSweepingMap2D_CUDA_v4_impl.h"
+//#include "tnlFastSweepingMap2D_CUDA_v5_impl.h"
+
+
+//															#include "tnlFastSweepingMap3D_CUDA_impl.h"
+
+#endif /* TNLFASTSWEEPING_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7a2963cc680e3a5c83f9116c19c715b3d44d7a42
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt
@@ -0,0 +1,22 @@
+set( tnl_fast_sweeping_SOURCES
+#     MainBuildConfig.h
+#     tnlFastSweeping2D_impl.h
+#     tnlFastSweeping.h
+#     fastSweepingConfig.h 
+     main.cpp)
+
+
+IF(  BUILD_CUDA ) 
+	CUDA_ADD_EXECUTABLE(fast-sweeping${debugExt} main.cu)
+ELSE(  BUILD_CUDA )                
+	ADD_EXECUTABLE(fast-sweeping${debugExt} main.cpp)
+ENDIF( BUILD_CUDA )
+target_link_libraries (fast-sweeping${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS fast-sweeping${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+#INSTALL( FILES ${tnl_fast_sweeping_SOURCES}
+#         DESTINATION share/tnl-${tnlVersion}/examples/fast-sweeping )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..3df2c1e889050448fc07baf7dcd0e32feab3f778
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+                          fastSweepingConfig.h  -  description
+                             -------------------
+    begin                : Oct 15, 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 FASTSWEEPINGCONFIG_H_
+#define FASTSWEEPINGCONFIG_H_
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class fastSweepingConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Parallel Eikonal solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" );
+         config.addRequiredEntry        < String > ( "initial-condition", "Initial condition for solver");
+         config.addRequiredEntry        < int > ( "dim", "Dimension of problem.");
+         config.addEntry       < String > ( "mesh", "Name of mesh.", "mesh.tnl" );
+         config.addEntry       < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" );
+      }
+};
+
+#endif /* FASTSWEEPINGCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu
new file mode 100644
index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..8aca8f1b81db3a4a462d231e4724f3eef50e4723
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+                          main.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "MainBuildConfig.h"
+	//for HOST versions:
+#include "tnlFastSweeping.h"
+	//for DEVICE versions:
+//#include "tnlFastSweeping_CUDA.h"
+#include "fastSweepingConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+
+#include <mesh/tnlGrid.h>
+#include <core/tnlDevice.h>
+#include <time.h>
+#include <ctime>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+	time_t start;
+	time_t stop;
+	time(&start);
+	std::clock_t start2= std::clock();
+   Config::ParameterContainer parameters;
+   tnlConfigDescription configDescription;
+   fastSweepingConfig< BuildConfig >::configSetup( configDescription );
+
+   if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
+      return false;
+
+   const int& dim = parameters.getParameter< int >( "dim" );
+
+   if(dim == 2)
+   {
+		tnlFastSweeping<tnlGrid<2,double,TNL::Devices::Host, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		TNL_CHECK_CUDA_DEVICE;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+   else if(dim == 3)
+   {
+		tnlFastSweeping<tnlGrid<3,double,TNL::Devices::Host, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		TNL_CHECK_CUDA_DEVICE;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+   else
+   {
+	   cerr << "Unsupported number of dimensions: " << dim << "!" << endl;
+	   return EXIT_FAILURE;
+   }
+
+
+   time(&stop);
+   cout << "Solver stopped..." << endl;
+   cout << endl;
+   cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h
new file mode 100644
index 0000000000000000000000000000000000000000..96d26db7b5a2077d8e2199292f0e888b0171a5c2
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+                          tnlFastSweeping.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING_H_
+#define TNLFASTSWEEPING_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+#ifdef HAVE_OPENMP
+#include <omp.h>
+#endif
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlFastSweeping
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+	tnlFastSweeping();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+
+	void setupSquare1000(Index i, Index j);
+	void setupSquare1100(Index i, Index j);
+	void setupSquare1010(Index i, Index j);
+	void setupSquare1001(Index i, Index j);
+	void setupSquare1110(Index i, Index j);
+	void setupSquare1101(Index i, Index j);
+	void setupSquare1011(Index i, Index j);
+	void setupSquare1111(Index i, Index j);
+	void setupSquare0000(Index i, Index j);
+	void setupSquare0100(Index i, Index j);
+	void setupSquare0010(Index i, Index j);
+	void setupSquare0001(Index i, Index j);
+	void setupSquare0110(Index i, Index j);
+	void setupSquare0101(Index i, Index j);
+	void setupSquare0011(Index i, Index j);
+	void setupSquare0111(Index i, Index j);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity;
+
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlFastSweeping();
+
+	static String getType();
+	bool init( const Config::ParameterContainer& parameters );
+
+	bool initGrid();
+	bool run();
+
+	//for single core version use this implementation:
+	void updateValue(const Index i, const Index j, const Index k);
+	//for parallel version use this one instead:
+//	void updateValue(const Index i, const Index j, DofVectorType* grid);
+
+	Real fabsMin(const Real x, const Real y);
+
+
+protected:
+
+	MeshType Mesh;
+
+	bool exactInput;
+
+
+	tnlMeshFunction<MeshType> dofVector, dofVector2;
+	DofVectorType data;
+
+	RealType h;
+
+	tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity;
+
+#ifdef HAVE_OPENMP
+//	omp_lock_t* gridLock;
+#endif
+
+
+};
+
+
+	//for single core version use this implementation:
+#include "tnlFastSweeping2D_impl.h"
+	//for parallel version use this one instead:
+// #include "tnlFastSweeping2D_openMP_impl.h"
+
+#include "tnlFastSweeping3D_impl.h"
+
+#endif /* TNLFASTSWEEPING_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..21e45020924453bd5676650028f6fdc6b210bc42
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h
@@ -0,0 +1,522 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.getSpaceSteps().x();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+//
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//
+//	dofVector.save("u-00001.tnl");
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(32, 32);
+	dim3 numBlocks(n/32 + 1 ,n/32 +1);
+
+	for(int i = 2*n - 1; i > -1; i--)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	for(int i = 0; i < 2*n ; i++)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	for(int i = 0; i < 2*n ; i++)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	for(int i = 2*n - 1; i > -1; i--)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,i);
+		cudaDeviceSynchronize();
+	}
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = cudaDofVector[index];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)];
+	else
+	{
+		a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)];
+	else
+	{
+		b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	cudaDofVector[index]  = fabsMin(value, tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gid = Mesh.getCellIndex(CoordinatesType(gx,gy));
+
+	int total = blockDim.x*gridDim.x;
+
+
+
+	Real tmp = 0.0;
+	int flag = 0;
+	counter = 0;
+	tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+
+
+	if(!exactInput)
+	{
+		cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]);
+	}
+	__threadfence();
+//	printf("-----------------------------------------------------------------------------------\n");
+
+	__threadfence();
+
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1)
+	{
+		if(gy > 0 && gy < Mesh.getDimensions().y()-1)
+		{
+
+			Index j = gy;
+			Index i = gx;
+//			 tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+			if(tmp == 0.0)
+			{}
+			else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+			{}
+			else
+				flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+		}
+	}
+
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+//	printf("****************************************************************\n");
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0)
+	{
+//		printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+		Index j = 0;
+		Index i = gx;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1)
+	{
+		Index i = gx;
+		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0)
+	{
+		Index j = gy;
+		Index i = 0;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+//	printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1  && gx == Mesh.getDimensions().x() - 1)
+	{
+		Index j = gy;
+		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("##################################################################################################\n");
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == 0)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+//	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
+	if(gx == 0 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == 0 &&
+	   gy == 0)
+	{
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+
+	__threadfence();
+
+	if(flag==1)
+		cudaDofVector[gid] =  tmp*3;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	Real fy = abs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+		return;
+	int total = solver->Mesh.getDimensions().x();
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	int id1 = gx+gy;
+	int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+	if(sweep == 1)
+//	for(int i = 0; i < 2*total - 1; i++)
+	{
+		if(id1 == i)
+		{
+			solver->updateValue(gx,gy);
+			return;
+		}
+
+	}
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+	else if(sweep == 2)
+//	for(int i = 0; i < 2*total - 1; i++)
+	{
+		if(id2 == i)
+		{
+			solver->updateValue(gx,gy);
+			return;
+		}
+	}
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+	else if(sweep == 3)
+//	for(int i = 2*total - 2; i > -1; i--)
+	{
+		if(id1 == i)
+		{
+			solver->updateValue(gx,gy);
+			return;
+		}
+	}
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+	else if(sweep == 4)
+//	for(int i = 2*total - 2; i > -1; i--)
+	{
+		if(id2 == i)
+		{
+			solver->updateValue(gx,gy);
+			return;
+		}
+	}
+	/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d4ee11b0856a618f7b86452828a2bd2e71bf24e
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h
@@ -0,0 +1,588 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_v2_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.getSpaceSteps().x();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+//
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//
+//	dofVector.save("u-00001.tnl");
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(27, 27);
+	dim3 numBlocks(1 ,1);
+
+//	for(int i = 2*n - 1; i > -1; i--)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,0);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+////	for(int i = 0; i < 2*n ; i++)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,0);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+////	for(int i = 0; i < 2*n ; i++)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,0);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+////	for(int i = 2*n - 1; i > -1; i--)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,0);
+//		cudaDeviceSynchronize();
+//	}
+//
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = cudaDofVector[index];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)];
+	else
+	{
+		a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)];
+	else
+	{
+		b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	cudaDofVector[index]  = fabsMin(value, tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gid = Mesh.getCellIndex(CoordinatesType(gx,gy));
+
+	int total = blockDim.x*gridDim.x;
+
+
+
+	Real tmp = 0.0;
+	int flag = 0;
+	counter = 0;
+	tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+
+
+	if(!exactInput)
+	{
+		cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]);
+	}
+	__threadfence();
+//	printf("-----------------------------------------------------------------------------------\n");
+
+	__threadfence();
+
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1)
+	{
+		if(gy > 0 && gy < Mesh.getDimensions().y()-1)
+		{
+
+			Index j = gy;
+			Index i = gx;
+//			 tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+			if(tmp == 0.0)
+			{}
+			else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+			{}
+			else
+				flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+		}
+	}
+
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+//	printf("****************************************************************\n");
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0)
+	{
+//		printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+		Index j = 0;
+		Index i = gx;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1)
+	{
+		Index i = gx;
+		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0)
+	{
+		Index j = gy;
+		Index i = 0;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+//	printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1  && gx == Mesh.getDimensions().x() - 1)
+	{
+		Index j = gy;
+		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("##################################################################################################\n");
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == 0)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+//	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
+	if(gx == 0 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == 0 &&
+	   gy == 0)
+	{
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+
+	__threadfence();
+
+	if(flag==1)
+		cudaDofVector[gid] =  tmp*3;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+
+	Real tmpMin = Min(fx,abs(y));
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+{
+
+	//int gx = threadIdx.x;
+	//int gy = threadIdx.y;
+	int id1,id2;
+	int nx = solver->Mesh.getDimensions().x()+ threadIdx.x;
+	int ny = solver->Mesh.getDimensions().y()+ threadIdx.y;
+
+	int blockCount = solver->Mesh.getDimensions().x()/blockDim.x + 1;
+
+	for(int gy = threadIdx.y; gy < ny;gy+=blockDim.y)
+	{
+		for(int gx = threadIdx.x; gx < nx;gx+=blockDim.x)
+		{
+//			if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1)
+			{
+				id1 = threadIdx.x+threadIdx.y;
+
+				for(int l = 0; l < 2*blockDim.x - 1; l++)
+				{
+					if(id1 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+					}
+					__syncthreads();
+				}
+
+			}
+			//gx+=blockDim.x;
+			//__syncthreads();
+		}
+		//gx = threadIdx.x;
+		//gy+=blockDim.y;
+		//__syncthreads();
+	}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+//	gx = blockDim.x*(blockCount-1) + threadIdx.x;
+//	gy = threadIdx.y;
+	for(int gy = threadIdx.y; gy < ny;gy+=blockDim.y)
+	{
+		for(int gx = blockDim.x*(blockCount-1) + threadIdx.x; gx >- 1;gx-=blockDim.x)
+		{
+//			if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1)
+			{
+				id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+				for(int l = 0; l < 2*blockDim.x - 1; l++)
+				{
+					if(id2 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+					}
+					__syncthreads();
+				}
+			}
+			//gx-=blockDim.x;
+			//__syncthreads();
+		}
+		//gx = blockDim.x*(blockCount-1) + threadIdx.x;
+		//gy+=blockDim.y;
+		//__syncthreads();
+	}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+//	gx = blockDim.x*(blockCount-1) + threadIdx.x;
+//	gy = blockDim.x*(blockCount-1) + threadIdx.y;
+	for(int gy = blockDim.x*(blockCount-1) +threadIdx.y; gy >- 1;gy-=blockDim.y)
+	{
+		for(int gx = blockDim.x*(blockCount-1) + threadIdx.x; gx >- 1;gx-=blockDim.x)
+		{
+//			if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1)
+			{
+				id1 = threadIdx.x+threadIdx.y;
+
+				for(int l = 2*blockDim.x - 2; l > -1; l--)
+				{
+					if(id1 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+					}
+					__syncthreads();
+				}
+			}
+			//gx-=blockDim.x;
+			//__syncthreads();
+		}
+		//gx = blockDim.x*(blockCount-1) + threadIdx.x;
+		//gy-=blockDim.y;
+		//__syncthreads();
+	}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+	//gx = threadIdx.x;
+	//gy = blockDim.x*(blockCount-1) +threadIdx.y;
+	for(int gy = blockDim.x*(blockCount-1) +threadIdx.y; gy >- 1;gy-=blockDim.y)
+	{
+		for(int gx = threadIdx.x; gx < nx;gx+=blockDim.x)
+		{
+//			if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1)
+			{
+				id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+				for(int l = 2*blockDim.x - 2; l > -1; l--)
+				{
+					if(id2 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+					}
+					__syncthreads();
+				}
+			}
+			//gx+=blockDim.x;
+			//__syncthreads();
+		}
+		//gx = threadIdx.x;
+		//gy-=blockDim.y;
+		///__syncthreads();
+	}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..fad3bc293cc452c1fe077e892b13b51750a78bb6
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h
@@ -0,0 +1,920 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_v3_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+
+
+
+__device__ double atomicSet(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong(val ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.getSpaceSteps().x();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+//
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//
+//	dofVector.save("u-00001.tnl");
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 +1 ,n/16 +1);
+	int m =n/16 +1;
+
+	for(int i = 0; i < 2*m -1; i++)
+	{
+		runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i);
+		//cudaDeviceSynchronize();
+	}
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+//	for(int i = 0; i < 2*m -1; i++)
+//	{
+//		runCUDA<2><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+//	for(int i = 0; i < 2*m -1; i++)
+//	{
+//		runCUDA<4><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	TNL_CHECK_CUDA_DEVICE;
+//	for(int i = 0; i < 2*m -1; i++)
+//	{
+//		runCUDA<8><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,8,i);
+//		cudaDeviceSynchronize();
+//	}
+
+
+
+
+//	for(int i = 0; i < (2*m -1)/4 -1; i++)
+//	{
+//		runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,15,i);//all
+//		cudaDeviceSynchronize();
+//	}
+//	for(int i = (2*m -1)/4 -1; i < (2*m -1)/2 -1; i++)
+//	{
+//		runCUDA<5><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,5,i); //two
+//		cudaDeviceSynchronize();
+//		runCUDA<10><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,10,i); //two
+//		cudaDeviceSynchronize();
+//	}
+//	for(int i = (2*m -1)/2 -1; i < (2*m -1)/2 +1; i++)
+//	{
+//		runCUDA<1><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i); //separate
+//		cudaDeviceSynchronize();
+//		runCUDA<2><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i); //separate
+//		cudaDeviceSynchronize();
+//		runCUDA<4><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i); //separate
+//		cudaDeviceSynchronize();
+//		runCUDA<8><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,8,i); //separate
+//		cudaDeviceSynchronize();
+//	}
+//	for(int i = (2*m -1)/2 +1; i < (2*m -1/4)*3 +1; i++)
+//	{
+//		runCUDA<5><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,5,i); //two
+//		cudaDeviceSynchronize();
+//		runCUDA<10><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,10,i); //two
+//		cudaDeviceSynchronize();
+//	}
+//	for(int i = (2*m -1/4)*3 +1; i < 2*m -1; i++)
+//	{
+//		runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,15,i);//all
+//		cudaDeviceSynchronize();
+//	}
+cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = cudaDofVector[index];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)];
+	else
+	{
+		a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)];
+	else
+	{
+		b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	atomicSet(&cudaDofVector[index],fabsMin(value, tmp));
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gid = Mesh.getCellIndex(CoordinatesType(gx,gy));
+
+	int total = blockDim.x*gridDim.x;
+
+
+
+	Real tmp = 0.0;
+	int flag = 0;
+	counter = 0;
+	tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+
+
+	if(!exactInput)
+	{
+		cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]);
+	}
+	__threadfence();
+//	printf("-----------------------------------------------------------------------------------\n");
+
+	__threadfence();
+
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1)
+	{
+		if(gy > 0 && gy < Mesh.getDimensions().y()-1)
+		{
+
+			Index j = gy;
+			Index i = gx;
+//			 tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+			if(tmp == 0.0)
+			{}
+			else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+			{}
+			else
+				flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+		}
+	}
+
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+//	printf("****************************************************************\n");
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0)
+	{
+//		printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+		Index j = 0;
+		Index i = gx;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1)
+	{
+		Index i = gx;
+		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0)
+	{
+		Index j = gy;
+		Index i = 0;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+//	printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1  && gx == Mesh.getDimensions().x() - 1)
+	{
+		Index j = gy;
+		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("##################################################################################################\n");
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == 0)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+//	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
+	if(gx == 0 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == 0 &&
+	   gy == 0)
+	{
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+
+	__threadfence();
+
+	if(flag==1)
+		cudaDofVector[gid] =  tmp*3;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+//	Real fx = abs(x);
+//
+//	Real tmpMin = Min(fx,abs(y));
+
+	if(abs(y) > abs(x))
+		return x;
+	else
+		return y;
+
+
+}
+
+
+template<>
+__global__ void runCUDA<1>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+{
+
+	if(blockIdx.x+blockIdx.y == k)
+	{
+		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+		int id1 = threadIdx.x+threadIdx.y;
+
+						for(int l = 0; l < 2*blockDim.x - 1; l++)
+						{
+							if(id1 == l)
+							{
+								if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+								solver->updateValue(gx,gy);
+							}
+							__syncthreads();
+						}
+
+	}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+}
+	template<>
+	__global__ void runCUDA<2>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+	{
+	if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k)
+	{
+		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+		int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+				for(int l = 0; l < 2*blockDim.x - 1; l++)
+				{
+					if(id2 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+					}
+					__syncthreads();
+				}
+
+	}
+	}			/*---------------------------------------------------------------------------------------------------------------------------*/
+	template<>
+	__global__ void runCUDA<4>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+	{
+	if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2)
+		{
+		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+		int id1 = threadIdx.x+threadIdx.y;
+
+				for(int l = 2*blockDim.x - 2; l > -1; l--)
+				{
+					if(id1 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+						return;
+					}
+					__syncthreads();
+				}
+
+		}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	}
+
+	template<>
+	__global__ void runCUDA<8>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+	{
+	if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2)
+		{
+		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+		int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+				for(int l = 2*blockDim.x - 2; l > -1; l--)
+				{
+					if(id2 == l)
+					{
+						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+						solver->updateValue(gx,gy);
+						return;
+					}
+					__syncthreads();
+				}
+
+		}
+			/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+}
+
+
+	template<>
+		__global__ void runCUDA<5>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+		{
+
+			if(blockIdx.x+blockIdx.y == k)
+			{
+				int gx = threadIdx.x + blockDim.x*blockIdx.x;
+				int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+				int id1 = threadIdx.x+threadIdx.y;
+
+								for(int l = 0; l < 2*blockDim.x - 1; l++)
+								{
+									if(id1 == l)
+									{
+										if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+										solver->updateValue(gx,gy);
+										return;
+									}
+									__syncthreads();
+								}
+
+			}
+			else if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2)
+				{
+				int gx = threadIdx.x + blockDim.x*blockIdx.x;
+				int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+				int id1 = threadIdx.x+threadIdx.y;
+
+						for(int l = 2*blockDim.x - 2; l > -1; l--)
+						{
+							if(id1 == l)
+							{
+								if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+								solver->updateValue(gx,gy);
+								return;
+							}
+							__syncthreads();
+						}
+
+				}
+		}
+
+
+	template<>
+		__global__ void runCUDA<10>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+		{
+			if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k)
+			{
+				int gx = threadIdx.x + blockDim.x*blockIdx.x;
+				int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+				int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+						for(int l = 0; l < 2*blockDim.x - 1; l++)
+						{
+							if(id2 == l)
+							{
+								if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+								solver->updateValue(gx,gy);
+								return;
+							}
+							__syncthreads();
+						}
+
+			}
+
+			else if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2)
+				{
+				int gx = threadIdx.x + blockDim.x*blockIdx.x;
+				int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+				int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+						for(int l = 2*blockDim.x - 2; l > -1; l--)
+						{
+							if(id2 == l)
+							{
+								if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+								solver->updateValue(gx,gy);
+								return;
+							}
+							__syncthreads();
+						}
+
+				}
+
+		}
+
+
+
+	template<>
+	__global__ void runCUDA<15>(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+	{
+
+		if(blockIdx.x+blockIdx.y == k)
+		{
+			int gx = threadIdx.x + blockDim.x*blockIdx.x;
+			int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+			int id1 = threadIdx.x+threadIdx.y;
+
+							for(int l = 0; l < 2*blockDim.x - 1; l++)
+							{
+								if(id1 == l)
+								{
+									if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+									solver->updateValue(gx,gy);
+									return;
+								}
+								__syncthreads();
+							}
+
+		}
+				/*---------------------------------------------------------------------------------------------------------------------------*/
+
+		if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k)
+		{
+			int gx = threadIdx.x + blockDim.x*blockIdx.x;
+			int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+			int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+					for(int l = 0; l < 2*blockDim.x - 1; l++)
+					{
+						if(id2 == l)
+						{
+							if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+							solver->updateValue(gx,gy);
+							return;
+						}
+						__syncthreads();
+					}
+
+		}
+				/*---------------------------------------------------------------------------------------------------------------------------*/
+
+		if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2)
+			{
+			int gx = threadIdx.x + blockDim.x*blockIdx.x;
+			int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+			int id1 = threadIdx.x+threadIdx.y;
+
+					for(int l = 2*blockDim.x - 2; l > -1; l--)
+					{
+						if(id1 == l)
+						{
+							if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+							solver->updateValue(gx,gy);
+							return;
+						}
+						__syncthreads();
+					}
+
+			}
+				/*---------------------------------------------------------------------------------------------------------------------------*/
+
+		if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2)
+			{
+			int gx = threadIdx.x + blockDim.x*blockIdx.x;
+			int gy = threadIdx.y + blockDim.y*blockIdx.y;
+
+			int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+
+					for(int l = 2*blockDim.x - 2; l > -1; l--)
+					{
+						if(id2 == l)
+						{
+							if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+							solver->updateValue(gx,gy);
+							return;
+						}
+						__syncthreads();
+					}
+
+			}
+				/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+	}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+#endif
+
+
+
+
+
+
+//__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int k)
+//{
+//
+//	if(sweep==1 && blockIdx.x+blockIdx.y == k)
+//	{
+//		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+//		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+//
+//		int id1 = threadIdx.x+threadIdx.y;
+//
+//						for(int l = 0; l < 2*blockDim.x - 1; l++)
+//						{
+//							if(id1 == l)
+//							{
+//								if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+//								solver->updateValue(gx,gy);
+//							}
+//							__syncthreads();
+//						}
+//
+//	}
+//			/*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	else if(sweep==2 && (gridDim.x - blockIdx.x - 1)+blockIdx.y == k)
+//	{
+//		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+//		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+//
+//		int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+//
+//				for(int l = 0; l < 2*blockDim.x - 1; l++)
+//				{
+//					if(id2 == l)
+//					{
+//						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+//						solver->updateValue(gx,gy);
+//					}
+//					__syncthreads();
+//				}
+//
+//	}
+//			/*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	else if(sweep==4 && blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2)
+//		{
+//		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+//		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+//
+//		int id1 = threadIdx.x+threadIdx.y;
+//
+//				for(int l = 2*blockDim.x - 2; l > -1; l--)
+//				{
+//					if(id1 == l)
+//					{
+//						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+//						solver->updateValue(gx,gy);
+//						return;
+//					}
+//					__syncthreads();
+//				}
+//
+//		}
+//			/*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	else if(sweep==8 && (gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2)
+//		{
+//		int gx = threadIdx.x + blockDim.x*blockIdx.x;
+//		int gy = threadIdx.y + blockDim.y*blockIdx.y;
+//
+//		int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y;
+//
+//				for(int l = 2*blockDim.x - 2; l > -1; l--)
+//				{
+//					if(id2 == l)
+//					{
+//						if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/)
+//						solver->updateValue(gx,gy);
+//						return;
+//					}
+//					__syncthreads();
+//				}
+//
+//		}
+//			/*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//
+//
+//
+//
+//}
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd878d4953d46ac014622a43e03ad0e8b6b9a492
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h
@@ -0,0 +1,1003 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping()
+:dofVector(Mesh)
+{
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	//Entity.refresh();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(1, 1024);
+	dim3 numBlocks(4,1);
+
+
+	runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	//data.setLike(dofVector.getData());
+	//cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	//data.save("u-00001.tnl");
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+//	cudaDofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+	atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int i = threadIdx.x + blockDim.x*blockIdx.x;
+	int j = blockDim.y*blockIdx.y + threadIdx.y;
+
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	int gid = Entity.getIndex();
+
+	cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]);
+//
+//	if(abs(cudaDofVector[gid]) < 1.01*h)
+//		cudaDofVector2[gid] = cudaDofVector[gid];
+
+
+
+
+
+	if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() && !exactInput)
+	{
+		if(cudaDofVector[Entity.getIndex()] > 0)
+		{
+			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+			{
+				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1111(i,j);
+					else
+						setupSquare1110(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1101(i,j);
+					else
+						setupSquare1100(i,j);
+				}
+			}
+			else
+			{
+				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1011(i,j);
+					else
+						setupSquare1010(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1001(i,j);
+					else
+						setupSquare1000(i,j);
+				}
+			}
+		}
+		else
+		{
+			if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+			{
+				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0111(i,j);
+					else
+						setupSquare0110(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0101(i,j);
+					else
+						setupSquare0100(i,j);
+				}
+			}
+			else
+			{
+				if(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0011(i,j);
+					else
+						setupSquare0010(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0001(i,j);
+					else
+						setupSquare0000(i,j);
+				}
+			}
+		}
+
+	}
+	if(exactInput)
+	{
+		if(abs(cudaDofVector[gid]) < 1.5*h)
+			cudaDofVector2[gid] = cudaDofVector[gid];
+	}
+
+
+	return true;
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	//Real fy = abs(y);
+
+	//Real tmpMin = Min(fx,abs(y));
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+	int gx = 0;
+	int gy = threadIdx.y;
+	//if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+	//	return;
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	//int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	//int id1 = gx+gy;
+	//int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+	if(blockIdx.x==0)
+	{
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+
+
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+//	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+//	Entity.setCoordinates(CoordinatesType(i,j));
+//	Entity.refresh();
+//	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+//	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+//	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+//	Entity.setCoordinates(CoordinatesType(i,j));
+//	Entity.refresh();
+//	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+//	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=INT_MAX;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=INT_MAX;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-INT_MAX;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-INT_MAX;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b = 1.0;
+	c = -be;
+	s = h/sqrt(a*a+b*b);
+
+
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	tnlGridEntity< tnlGrid< 2,double, TNL::Devices::Host, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(cudaDofVector[neighborEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f8c90df818b7121663e8053b0577d37fd119055
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h
@@ -0,0 +1,697 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_v5_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.getSpaceSteps().x();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);
+
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+//
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+//	{
+//		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+//		{
+//			updateValue(i,j);
+//		}
+//	}
+//
+///*---------------------------------------------------------------------------------------------------------------------------*/
+//
+//
+//	dofVector.save("u-00001.tnl");
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(1, 512);
+	dim3 numBlocks(4,1);
+
+
+	runCUDA<<<numBlocks,threadsPerBlock,3*(512+1)*sizeof(double)>>>(this->cudaSolver,0,0);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = cudaDofVector[index];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)];
+	else
+	{
+		a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)];
+	else
+	{
+		b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)],
+				 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+	cudaDofVector[index]  = fabsMin(value, tmp);
+
+}
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, double** sharedMem, int k3)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = sharedMem[k3+1][threadIdx.y];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = sharedMem[k3][threadIdx.y];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = sharedMem[k3+2][threadIdx.y];
+	else
+	{
+		a = fabsMin( sharedMem[k3][threadIdx.y],
+				sharedMem[k3+2][threadIdx.y] );
+	}
+
+	if( j == 0 )
+		b = sharedMem[k3][threadIdx.y+1];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = sharedMem[k3+2][threadIdx.y-1];
+	else
+	{
+		b = fabsMin( sharedMem[k3][threadIdx.y+1],
+				sharedMem[k3+2][threadIdx.y-1] );
+	}
+
+
+	if(abs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+//	sharedMem[k3+1][threadIdx.y] = this->fabsMin(value, tmp);
+//	atomicFabsMin(&(cudaDofVector[index]), tmp);
+	cudaDofVector[index]  = tmp;
+	this->fabsMin(value, tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gid = Mesh.getCellIndex(CoordinatesType(gx,gy));
+
+	int total = blockDim.x*gridDim.x;
+
+
+
+	Real tmp = 0.0;
+	int flag = 0;
+	counter = 0;
+	tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+
+
+	if(!exactInput)
+	{
+		cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]);
+	}
+	__threadfence();
+//	printf("-----------------------------------------------------------------------------------\n");
+
+	__threadfence();
+
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1)
+	{
+		if(gy > 0 && gy < Mesh.getDimensions().y()-1)
+		{
+
+			Index j = gy;
+			Index i = gx;
+//			 tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+			if(tmp == 0.0)
+			{}
+			else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+					cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+			{}
+			else
+				flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+		}
+	}
+
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+//	printf("****************************************************************\n");
+//	printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0)
+	{
+//		printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid);
+		Index j = 0;
+		Index i = gx;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+	if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1)
+	{
+		Index i = gx;
+		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0)
+	{
+		Index j = gy;
+		Index i = 0;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+//	printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+	if(gy > 0 && gy < Mesh.getDimensions().y()-1  && gx == Mesh.getDimensions().x() - 1)
+	{
+		Index j = gy;
+		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+//	printf("##################################################################################################\n");
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == Mesh.getDimensions().x() - 1 &&
+	   gy == 0)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+//	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
+	if(gx == 0 &&
+	   gy == Mesh.getDimensions().y() - 1)
+	{
+
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+	if(gx == 0 &&
+	   gy == 0)
+	{
+//		tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]);
+		if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 &&
+				cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0)
+
+			flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX;
+	}
+
+	__threadfence();
+
+	if(flag==1)
+		cudaDofVector[gid] =  tmp*3;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	//Real fy = abs(y);
+
+	//Real tmpMin = Min(fx,abs(y));
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+	extern __shared__ double u[];
+	double* sharedMem[5];
+	sharedMem[0] = u;
+	sharedMem[1] = &(u[blockDim.y+1]);
+	sharedMem[2] = &(sharedMem[1][blockDim.y+1]);
+	sharedMem[3] = sharedMem[1];
+	sharedMem[4] = sharedMem[2];
+
+	int gx = 0;
+	int gy = threadIdx.y;
+	//if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy)
+	//	return;
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+	//int gid = solver->Mesh.getDimensions().x() * gy + gx;
+	//int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x();
+
+	//int id1 = gx+gy;
+	//int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy;
+
+
+	if(blockIdx.x==0)
+	{
+		if(threadIdx.y==0)
+			sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,0))];
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				int k3=k%3;
+
+				if(threadIdx.y==0)
+				{
+					if(gx==n-1)
+						sharedMem[k3][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,gy+blockDim.y))];
+					else
+						sharedMem[k3][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))];
+				}
+//				else
+//					solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3+2][threadIdx.y-1];
+
+				if(gy<n-1)
+					sharedMem[k3][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))];
+
+				solver->updateValue(gx,gy,sharedMem,k3);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+	}
+//	else if(blockIdx.x==1)
+//	{
+//		gx=n-1;
+//		gy=threadIdx.y;
+//
+//		if(threadIdx.y==0)
+//					sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,0))];
+//
+//		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+//		{
+//			if(threadIdx.y  < k+1 && gy < n)
+//			{
+//				int k3=k%3;
+//
+//				if(threadIdx.y==0)
+//					if(gx==0)
+//						sharedMem[k3+2][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,gy+blockDim.y))];
+//					else
+//						sharedMem[k3+2][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx-1,gy))];
+//				else
+//					solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3][threadIdx.y-1];
+//
+//				if(gy<n-1)
+//					sharedMem[k3+2][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))];
+//
+//
+//				solver->updateValue(gx,gy,sharedMem,k3);
+//				gx--;
+//				if(gx==-1)
+//				{
+//					gx=n-1;
+//					gy+=blockDim.y;
+//				}
+//			}
+//
+//
+//			__syncthreads();
+//		}
+//	}
+//	else if(blockIdx.x==2)
+//	{
+//		gx=0;
+//		gy=n-blockDim.y-1+threadIdx.y;
+//
+//		if(threadIdx.y==0)
+//					sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,n-1))];
+//
+//		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+//		{
+//			if(blockDim.y-threadIdx.y  < k+1 && gy > -1)
+//			{
+//				int k3=k%3;
+//
+//				if(threadIdx.y==blockDim.y-1)
+//					if(gx==n-1)
+//						sharedMem[k3][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,gy-blockDim.y))];
+//					else
+//						sharedMem[k3][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))];
+//				else
+//					solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3+2][threadIdx.y-1];
+//
+//				if(gy<n-1)
+//					sharedMem[k3][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))];
+//
+//
+//				solver->updateValue(gx,gy,sharedMem,k3);
+//				gx++;
+//				if(gx==n)
+//				{
+//					gx=0;
+//					gy-=blockDim.y;
+//				}
+//			}
+//
+//
+//			__syncthreads();
+//		}
+//	}
+//	else if(blockIdx.x==3)
+//	{
+//		gx=n-1;
+//		gy=n-blockDim.y-1+threadIdx.y;
+//
+//		if(threadIdx.y==0)
+//					sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,n-1))];
+//
+//
+//		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+//		{
+//			if(blockDim.y-threadIdx.y  < k+1 && gy > -1)
+//			{
+//				int k3=k%3;
+//
+//				if(threadIdx.y==blockDim.y-1)
+//					if(gx==n-1)
+//						sharedMem[k3+2][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,gy-blockDim.y))];
+//					else
+//						sharedMem[k3+2][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))];
+//				else
+//					solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3][threadIdx.y-1];
+//
+//				if(gy<n-1)
+//					sharedMem[k3+2][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))];
+//
+//
+//				solver->updateValue(gx,gy,sharedMem,k3);
+//				gx--;
+//				if(gx==-1)
+//				{
+//					gx=n-1;
+//					gy-=blockDim.y;
+//				}
+//			}
+//
+//
+//			__syncthreads();
+//		}
+//	}
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy)
+	{
+		solver->initGrid();
+	}
+
+
+}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..8fd78cea97230d16135ddd03903442bb9922e0b8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h
@@ -0,0 +1,927 @@
+/***************************************************************************
+                          tnlFastSweeping2D_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping()
+:Entity(Mesh),
+ dofVector(Mesh),
+ dofVector2(Mesh)
+{
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+	dofVector2.load(initialCondition);
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0 >();
+	Entity.refresh();
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+	cout << "a" << endl;
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+	for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++)
+	{
+		dofVector2[i]=INT_MAX*sign(dofVector[i]);
+	}
+
+	for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++)
+	{
+		for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++)
+			{
+			this->Entity.setCoordinates(CoordinatesType(i,j));
+			this->Entity.refresh();
+			neighborEntities.refresh(Mesh,Entity.getIndex());
+
+				if(dofVector[this->Entity.getIndex()] > 0)
+				{
+					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1111(i,j);
+							else
+								setupSquare1110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1101(i,j);
+							else
+								setupSquare1100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1011(i,j);
+							else
+								setupSquare1010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1001(i,j);
+							else
+								setupSquare1000(i,j);
+						}
+					}
+				}
+				else
+				{
+					if(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0111(i,j);
+							else
+								setupSquare0110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0101(i,j);
+							else
+								setupSquare0100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0011(i,j);
+							else
+								setupSquare0010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0001(i,j);
+							else
+								setupSquare0000(i,j);
+						}
+					}
+				}
+
+			}
+	}
+	cout << "a" << endl;
+
+//	Real tmp = 0.0;
+//	Real ax=0.5/sqrt(2.0);
+//
+//	if(!exactInput)
+//	{
+//		for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++)
+//				dofVector[i]=0.5*h*sign(dofVector[i]);
+//	}
+//
+//
+//	for(Index i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		for(Index j = 1; j < Mesh.getDimensions().y()-1; j++)
+//		{
+//			 tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//			if(tmp == 0.0)
+//			{}
+//			else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//					dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//			{}
+//			else
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//		}
+//	}
+//
+//
+//
+//	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		Index j = 0;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+//	{
+//		Index j = Mesh.getDimensions().y() - 1;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+//	{
+//		Index i = 0;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+//	{
+//		Index i = Mesh.getDimensions().x() - 1;
+//		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//
+//
+//		if(tmp == 0.0)
+//		{}
+//		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+//				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+//		{}
+//		else
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//	}
+//
+//
+//	Index i = Mesh.getDimensions().x() - 1;
+//	Index j = Mesh.getDimensions().y() - 1;
+//
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	j = 0;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	i = 0;
+//	j = Mesh.getDimensions().y() -1;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+//
+//
+//
+//	j = 0;
+//	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+//	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+//			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+//
+//		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+	//data.setLike(dofVector2.getData());
+	//data=dofVector2.getData();
+	//cout << data.getType() << endl;
+	dofVector2.save("u-00000.tnl");
+	//dofVector2.getData().save("u-00000.tnl");
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+//	data.setLike(dofVector2.getData());
+//	data = dofVector2.getData();
+//	cout << data.getType() << endl;
+	dofVector2.save("u-00001.tnl");
+	//dofVector2.getData().save("u-00001.tnl");
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j)
+{
+
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighborEntities.template getEntityIndex< -1,  0 >()],
+				 dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  -1 >()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()] );
+	}
+
+
+	if(fabs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+
+	dofVector2[Entity.getIndex()] = fabsMin(value, tmp);
+
+//	if(dofVector2[Entity.getIndex()] > 1.0)
+//		cout << value << "    " << tmp << " " << dofVector2[Entity.getIndex()] << endl;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+{
+//	this->Entity.setCoordinates(CoordinatesType(i,j));
+//	this->Entity.refresh();
+//	auto neighborEntities =  Entity.getNeighborEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	a = be/al;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-al;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighborEntities.template getEntityIndex< 0,  1 >()]));
+
+	a = al-be;
+	b=1.0;
+	c=-be;
+	s= h/sqrt(a*a+b*b);
+
+
+	dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j));
+	this->Entity.refresh();
+	auto neighborEntities =  Entity.getNeighborEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighborEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighborEntities.template getEntityIndex< 1,  0 >()]);
+}
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d766c62c528b76b61312c5c485692d6655ff8f90
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h
@@ -0,0 +1,399 @@
+/***************************************************************************
+                          tnlFastSweeping_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING2D_IMPL_H_
+#define TNLFASTSWEEPING2D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	h = Mesh.getSpaceSteps().x();
+
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+#ifdef HAVE_OPENMP
+//	gridLock = (omp_lock_t*) malloc(sizeof(omp_lock_t)*Mesh.getDimensions().x()*Mesh.getDimensions().y());
+//
+//	for(int i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++)
+//			omp_init_lock(&gridLock[i]);
+#endif
+
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+
+	Real tmp = 0.0;
+
+	if(!exactInput)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++)
+				dofVector[i]=0.5*h*sign(dofVector[i]);
+	}
+
+
+	for(Index i = 1; i < Mesh.getDimensions().x()-1; i++)
+	{
+		for(Index j = 1; j < Mesh.getDimensions().y()-1; j++)
+		{
+			 tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+			if(tmp == 0.0)
+			{}
+			else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+					dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+					dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+					dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+			{}
+			else
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+		}
+	}
+
+
+
+	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+	{
+		Index j = 0;
+		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 )
+		{}
+		else
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+	for(int i = 1; i < Mesh.getDimensions().x()-1; i++)
+	{
+		Index j = Mesh.getDimensions().y() - 1;
+		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+	{
+		Index i = 0;
+		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+	for(int j = 1; j < Mesh.getDimensions().y()-1; j++)
+	{
+		Index i = Mesh.getDimensions().x() - 1;
+		tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+
+
+		if(tmp == 0.0)
+		{}
+		else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ||
+				dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 )
+		{}
+		else
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+	}
+
+
+	Index i = Mesh.getDimensions().x() - 1;
+	Index j = Mesh.getDimensions().y() - 1;
+
+	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+
+		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+
+
+	j = 0;
+	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+	if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 &&
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+
+		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+
+
+	i = 0;
+	j = Mesh.getDimensions().y() -1;
+	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0)
+
+		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+
+
+	j = 0;
+	tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]);
+	if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 &&
+			dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0)
+
+		dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX;
+
+
+	dofVector.save("u-00000.tnl");
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	DofVectorType d2,d3,d4;
+	d2.setLike(dofVector);
+	d2=dofVector;
+	d3.setLike(dofVector);
+	d3=dofVector;
+	d4.setLike(dofVector);
+	d4=dofVector;
+
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel sections num_threads(4)
+	{
+	{
+#endif
+
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j,&dofVector);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+#ifdef HAVE_OPENMP
+	}
+#pragma omp section
+	{
+#endif
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+		{
+			updateValue(i,j,&d2);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+#ifdef HAVE_OPENMP
+	}
+#pragma omp section
+	{
+#endif
+	for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j, &d3);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+#ifdef HAVE_OPENMP
+	}
+#pragma omp section
+	{
+#endif
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			updateValue(i,j, &d4);
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+#ifdef HAVE_OPENMP
+	}
+	}
+#endif
+
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for num_threads(4) schedule(dynamic)
+#endif
+	for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+	{
+		for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+		{
+			int index = Mesh.getCellIndex(CoordinatesType(i,j));
+			dofVector[index] = fabsMin(dofVector[index], d2[index]);
+			dofVector[index] = fabsMin(dofVector[index], d3[index]);
+			dofVector[index] = fabsMin(dofVector[index], d4[index]);
+		}
+	}
+
+	dofVector.save("u-00001.tnl");
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, DofVectorType* grid)
+{
+	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+	Real value = (*grid)[index];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = (*grid)[Mesh.template getCellNextToCell<1,0>(index)];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = (*grid)[Mesh.template getCellNextToCell<-1,0>(index)];
+	else
+	{
+		a = fabsMin( (*grid)[Mesh.template getCellNextToCell<-1,0>(index)],
+				 (*grid)[Mesh.template getCellNextToCell<1,0>(index)] );
+	}
+
+	if( j == 0 )
+		b = (*grid)[Mesh.template getCellNextToCell<0,1>(index)];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = (*grid)[Mesh.template getCellNextToCell<0,-1>(index)];
+	else
+	{
+		b = fabsMin( (*grid)[Mesh.template getCellNextToCell<0,-1>(index)],
+				 (*grid)[Mesh.template getCellNextToCell<0,1>(index)] );
+	}
+
+
+	if(fabs(a-b) >= h)
+		tmp = fabsMin(a,b) + sign(value)*h;
+	else
+		tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) );
+
+#ifdef HAVE_OPENMP
+//	omp_set_lock(&gridLock[index]);
+#endif
+	(*grid)[index]  = fabsMin(value, tmp);
+#ifdef HAVE_OPENMP
+//	omp_unset_lock(&gridLock[index]);
+#endif
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..51bb61716d1b49e2921d974e93692cdf0a34ddf1
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h
@@ -0,0 +1,961 @@
+/***************************************************************************
+                          tnlFastSweeping2D_CUDA_v4_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING3D_IMPL_H_
+#define TNLFASTSWEEPING3D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+//__device__
+//double fabsMin( double x, double y)
+//{
+//	double fx = abs(x);
+//
+//	if(Min(fx,abs(y)) == fx)
+//		return x;
+//	else
+//		return y;
+//}
+//
+//__device__
+//double atomicFabsMin(double* address, double val)
+//{
+//	unsigned long long int* address_as_ull =
+//						  (unsigned long long int*)address;
+//	unsigned long long int old = *address_as_ull, assumed;
+//	do {
+//		assumed = old;
+//			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) ));
+//	} while (assumed != old);
+//	return __longlong_as_double(old);
+//}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+	this->h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	counter = 0;
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+
+
+#ifdef HAVE_CUDA
+
+	cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+	cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double));
+	cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice);
+
+
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >));
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice);
+
+#endif
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(8, 8,8);
+	dim3 numBlocks(n/8 + 1, n/8 +1, n/8 +1);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	return true;
+}
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	int n = Mesh.getDimensions().x();
+	dim3 threadsPerBlock(1, 1024);
+	dim3 numBlocks(8,1);
+
+
+	runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0);
+
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+
+	cudaMemcpy(this->dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+	cudaDeviceSynchronize();
+	cudaFree(cudaDofVector);
+	cudaFree(cudaDofVector2);
+	cudaFree(cudaSolver);
+	dofVector.save("u-00001.tnl");
+	cudaDeviceSynchronize();
+	return true;
+}
+
+
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k)
+{
+	tnlGridEntity< tnlGrid< 3,double, TNL::Devices::Host, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 1,  0,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1,  0 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  1,  0 >()] );
+	}
+
+	if( k == 0 )
+		c = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  1 >()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1 >()];
+	else
+	{
+		c = fabsMin( cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1 >()],
+				 cudaDofVector2[neighborEntities.template getEntityIndex< 0,  0,  1 >()] );
+	}
+
+	Real hD = 3.0*h*h - 2.0*(a*a + b*b + c*c - a*b - a*c - b*c);
+
+	if(hD < 0.0)
+		tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h;
+	else
+		tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) );
+
+	atomicFabsMin(&cudaDofVector2[Entity.getIndex()],tmp);
+
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid(int i, int j, int k)
+{
+	tnlGridEntity< tnlGrid< 3,double, TNL::Devices::Host, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	int gid = Entity.getIndex();
+
+	if(abs(cudaDofVector[gid]) < 1.0*h)
+		cudaDofVector2[gid] = 0.5*h;//cudaDofVector[gid];
+	else
+		cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]);
+
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__device__
+Real tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = abs(x);
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+
+
+}
+
+
+
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i)
+{
+
+	int gx = 0;
+	int gy = threadIdx.y;
+
+	int n = solver->Mesh.getDimensions().x();
+	int blockCount = n/blockDim.y +1;
+
+	if(blockIdx.x==0)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx = 0;
+		gy = threadIdx.y;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		__syncthreads();
+		}
+	}
+	else if(blockIdx.x==1)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==2)
+	{
+
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==3)
+	{
+		for(int gz = 0; gz < n;gz++)
+		{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+
+
+
+
+	else if(blockIdx.x==4)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx = 0;
+		gy = threadIdx.y;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==5)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=n-1;
+		gy=threadIdx.y;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy < n)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy+=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==6)
+	{
+
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=0;
+		gy=n-threadIdx.y-1;
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx++;
+				if(gx==n)
+				{
+					gx=0;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+	else if(blockIdx.x==7)
+	{
+		for(int gz = n-1; gz > -1;gz--)
+		{
+		gx=n-1;
+		gy=n-threadIdx.y-1;
+
+		for(int k = 0; k < n*blockCount + blockDim.y; k++)
+		{
+			if(threadIdx.y  < k+1 && gy > -1)
+			{
+				solver->updateValue(gx,gy,gz);
+				gx--;
+				if(gx==-1)
+				{
+					gx=n-1;
+					gy-=blockDim.y;
+				}
+			}
+
+
+			__syncthreads();
+		}
+		}
+	}
+
+
+
+
+}
+
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver)
+{
+	int gx = threadIdx.x + blockDim.x*blockIdx.x;
+	int gy = blockDim.y*blockIdx.y + threadIdx.y;
+	int gz = blockDim.z*blockIdx.z + threadIdx.z;
+
+	if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && solver->Mesh.getDimensions().z() > gz)
+	{
+		solver->initGrid(gx,gy,gz);
+	}
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(INT_MAX,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(-INT_MAX,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	a = be/al;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-al;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//
+//
+//
+//
+//
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-al;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	Real al,be, a,b,c,s;
+//	al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]));
+//
+//	be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/
+//			(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]-
+//			 cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]));
+//
+//	a = al-be;
+//	b=1.0;
+//	c=-be;
+//	s= h/sqrt(a*a+b*b);
+//
+//
+//	cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//
+//}
+//
+//template< typename MeshReal,
+//          typename Device,
+//          typename MeshIndex,
+//          typename Real,
+//          typename Index >
+//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j)
+//{
+//	Index index = Mesh.getCellIndex(CoordinatesType(i,j));
+//	cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]);
+//	cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]);
+//}
+#endif
+
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc4fd4f866c19b09d17ad8b2c19d2907d581d1c8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h
@@ -0,0 +1,307 @@
+/***************************************************************************
+                          tnlFastSweeping2D_impl.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING3D_IMPL_H_
+#define TNLFASTSWEEPING3D_IMPL_H_
+
+#include "tnlFastSweeping.h"
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+String tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType()
+{
+	   return String( "tnlFastSweeping< " ) +
+	          MeshType::getType() + ", " +
+	          ::getType< Real >() + ", " +
+	          ::getType< Index >() + " >";
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping()
+:Entity(Mesh),
+ dofVector(Mesh),
+ dofVector2(Mesh)
+{
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters )
+{
+	const String& meshFile = parameters.getParameter< String >( "mesh" );
+
+	if( ! Mesh.load( meshFile ) )
+	{
+		   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+		   return false;
+	}
+
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	if( ! dofVector.load( initialCondition ) )
+	{
+		   cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl;
+		   return false;
+	}
+	dofVector2.load(initialCondition);
+
+	h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	Entity.refresh();
+
+	const String& exact_input = parameters.getParameter< String >( "exact-input" );
+
+	if(exact_input == "no")
+		exactInput=false;
+	else
+		exactInput=true;
+//	cout << "bla "<<endl;
+	return initGrid();
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid()
+{
+	for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().y()*Mesh.getDimensions().z();i++)
+	{
+
+		if (abs(dofVector[i]) < 1.8*h)
+			dofVector2[i]=dofVector[i];
+		else
+			dofVector2[i]=INT_MAX*sign(dofVector[i]);
+	}
+
+	return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run()
+{
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index k = 0; k < Mesh.getDimensions().z(); k++)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+
+
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = 0; j < Mesh.getDimensions().y(); j++)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+	for(Index k = Mesh.getDimensions().z() -1; k > -1; k--)
+	{
+		for(Index i = 0; i < Mesh.getDimensions().x(); i++)
+		{
+			for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--)
+			{
+				updateValue(i,j,k);
+			}
+		}
+	}
+
+/*---------------------------------------------------------------------------------------------------------------------------*/
+
+
+	dofVector2.save("u-00001.tnl");
+
+	cout << "bla 3"<<endl;
+	return true;
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k)
+{
+	this->Entity.setCoordinates(CoordinatesType(i,j,k));
+	this->Entity.refresh();
+	tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighborEntities.template getEntityIndex< 1,  0,  0>()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighborEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighborEntities.template getEntityIndex< -1,  0,  0>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 1,  0,  0>()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  1,  0>()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0>()];
+	else
+	{
+		b = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  -1,  0>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  1,  0>()] );
+	}
+
+	if( k == 0 )
+		c = dofVector2[neighborEntities.template getEntityIndex< 0,  0,  1>()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = dofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1>()];
+	else
+	{
+		c = fabsMin( dofVector2[neighborEntities.template getEntityIndex< 0,  0,  -1>()],
+				 dofVector2[neighborEntities.template getEntityIndex< 0,  0,  1>()] );
+	}
+
+	Real hD = 3.0*h*h - 2.0*(a*a+b*b+c*c-a*b-a*c-b*c);
+
+	if(hD < 0.0)
+		tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h;
+	else
+		tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) );
+
+
+	dofVector2[Entity.getIndex()]  = fabsMin(value, tmp);
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+Real tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y)
+{
+	Real fx = fabs(x);
+	Real fy = fabs(y);
+
+	Real tmpMin = Min(fx,fy);
+
+	if(tmpMin == fx)
+		return x;
+	else
+		return y;
+
+}
+
+
+
+#endif /* TNLFASTSWEEPING_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5e2e1d7dfecceceb47f34bc46480daaff9975ab
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h
@@ -0,0 +1,34 @@
+/* 
+ * File:   tnlFastSweepingSolver.h
+ * Author: oberhuber
+ *
+ * Created on July 12, 2016, 6:04 PM
+ */
+
+#pragma once
+
+#include <functions/tnlConstantFunction.h>
+#include <problems/tnlPDEProblem.h>
+
+template< typename Mesh,
+          typename Anisotropy = tnlConstanstFunction< Mesh > >
+class tnlFastSweepingSolver  : public tnlPDEProblem< Mesh,
+                                                     typename Mesh::RealType,
+                                                     typename Mesh::DeviceType,
+                                                     typename Mesh::IndexType  >
+{
+   public:
+
+      typedef typename DifferentialOperator::RealType RealType;
+      typedef typename Mesh::DeviceType DeviceType;
+      typedef typename DifferentialOperator::IndexType IndexType;
+
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
+      typedef tnlPDEProblem< Mesh, TimeDependentProblem, RealType, DeviceType, IndexType > BaseType;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+};
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h
new file mode 100644
index 0000000000000000000000000000000000000000..f531da431bfec5d16da8ea7deabe6595031a0873
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+                          tnlFastSweeping_CUDA.h  -  description
+                             -------------------
+    begin                : Oct 15 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLFASTSWEEPING_H_
+#define TNLFASTSWEEPING_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+
+#include <functions/tnlMeshFunction.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+#include <ctime>
+
+
+
+
+
+template< typename Mesh,
+		  typename Real,
+		  typename Index >
+class tnlFastSweeping
+{};
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 2, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+	tnlFastSweeping();
+
+	__host__ static String getType();
+	__host__ bool init( const Config::ParameterContainer& parameters );
+	__host__ bool run();
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid();
+	__device__ void updateValue(const Index i, const Index j);
+	__device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	int counter;
+	__device__ void setupSquare1000(Index i, Index j);
+	__device__ void setupSquare1100(Index i, Index j);
+	__device__ void setupSquare1010(Index i, Index j);
+	__device__ void setupSquare1001(Index i, Index j);
+	__device__ void setupSquare1110(Index i, Index j);
+	__device__ void setupSquare1101(Index i, Index j);
+	__device__ void setupSquare1011(Index i, Index j);
+	__device__ void setupSquare1111(Index i, Index j);
+	__device__ void setupSquare0000(Index i, Index j);
+	__device__ void setupSquare0100(Index i, Index j);
+	__device__ void setupSquare0010(Index i, Index j);
+	__device__ void setupSquare0001(Index i, Index j);
+	__device__ void setupSquare0110(Index i, Index j);
+	__device__ void setupSquare0101(Index i, Index j);
+	__device__ void setupSquare0011(Index i, Index j);
+	__device__ void setupSquare0111(Index i, Index j);
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data;
+
+
+	RealType h;
+
+
+};
+
+
+
+
+
+
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >
+{
+
+public:
+	typedef Real RealType;
+	typedef Device DeviceType;
+	typedef Index IndexType;
+	typedef tnlGrid< 3, Real, Device, Index > MeshType;
+	typedef TNL::Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
+	typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+
+	__host__ static String getType();
+	__host__ bool init( const Config::ParameterContainer& parameters );
+	__host__ bool run();
+
+#ifdef HAVE_CUDA
+	__device__ bool initGrid(int i, int j, int k);
+	__device__ void updateValue(const Index i, const Index j, const Index k);
+	__device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3);
+	__device__ Real fabsMin(const Real x, const Real y);
+
+	tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver;
+	double* cudaDofVector;
+	double* cudaDofVector2;
+	int counter;
+#endif
+
+	MeshType Mesh;
+
+protected:
+
+
+
+	bool exactInput;
+
+	tnlMeshFunction<MeshType> dofVector;
+	DofVectorType data;
+
+	RealType h;
+
+
+};
+
+
+
+
+
+
+
+#ifdef HAVE_CUDA
+//template<int sweep_t>
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i);
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, TNL::Devices::Host, int >, double, int >* solver);
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 3,double, TNL::Devices::Host, int >, double, int >* solver);
+#endif
+
+/*various implementtions.... choose one*/
+//#include "tnlFastSweeping2D_CUDA_impl.h"
+//#include "tnlFastSweeping2D_CUDA_v2_impl.h"
+//#include "tnlFastSweeping2D_CUDA_v3_impl.h"
+#include "tnlFastSweeping2D_CUDA_v4_impl.h"
+//#include "tnlFastSweeping2D_CUDA_v5_impl.h"
+
+
+#include "tnlFastSweeping3D_CUDA_impl.h"
+
+#endif /* TNLFASTSWEEPING_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bd5ed12005cdec8df667d4feae4a4e0f65dbf46e
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt
@@ -0,0 +1,23 @@
+set( tnl_hamilton_jacobi_parallel_map_SOURCES
+#     MainBuildConfig.h
+#     tnlParallelMapSolver2D_impl.h
+#     tnlParallelMapSolver.h
+#     parallelMapConfig.h 
+#	  main.cu
+     main.cpp)
+
+
+IF(  BUILD_CUDA ) 
+	CUDA_ADD_EXECUTABLE(hamilton-jacobi-parallel-map${debugExt} main.cu)
+ELSE(  BUILD_CUDA )                
+	ADD_EXECUTABLE(hamilton-jacobi-parallel-map${debugExt} main.cpp)
+ENDIF( BUILD_CUDA )
+target_link_libraries (hamilton-jacobi-parallel-map${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS hamilton-jacobi-parallel-map${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+#INSTALL( FILES ${tnl_hamilton_jacobi_parallel_map_SOURCES}
+#         DESTINATION share/tnl-${tnlVersion}/examples/hamilton-jacobi-parallel-map )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d4ae61983910a676269a23e3d992f5f46ea83a8f
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt
@@ -0,0 +1,32 @@
+tomas@tomas-linux:~/Desktop/VU_CPU_MAPA/work_dir$ gnuplot
+
+	G N U P L O T
+	Version 4.6 patchlevel 4    last modified 2013-10-02 
+	Build System: Linux x86_64
+
+	Copyright (C) 1986-1993, 1998, 2004, 2007-2013
+	Thomas Williams, Colin Kelley and many others
+
+	gnuplot home:     http://www.gnuplot.info
+	faq, bugs, etc:   type "help FAQ"
+	immediate help:   type "help"  (plot window: hit 'h')
+
+Terminal type set to 'wxt'
+gnuplot> set cntrparam levels 15
+gnuplot> set cntrparam bspline
+gnuplot> set contour
+gnuplot> splot 'u-00001.gplt'
+
+gnuplot> unset surface
+gnuplot> splot 'u-00001.gplt'
+
+gnuplot> set table "test.gplt"
+gnuplot> splot 'u-00001.gplt'
+gnuplot> unset table
+
+gnuplot> set table "test2.gplt"
+gnuplot> plot 'test.gplt' index 10
+gnuplot> unset table
+
+gnuplot> plot 'test2.gplt' 
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b13498e17330fae7bb00a0bdc2abcc7a19f8e7a8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu
new file mode 100644
index 0000000000000000000000000000000000000000..7101976712e153d73c5f0979b211164a36ec648d
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cu  -  description
+                             -------------------
+    begin                : Mar 30 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..911f0a29d9f0a82aa73767cfcee407093bc2eb66
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+                          main.h  -  description
+                             -------------------
+    begin                : Mar 22 , 2016
+    copyright            : (C) 2016 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "tnlParallelMapSolver.h"
+#include "parallelMapConfig.h"
+#include "MainBuildConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovMap.h>
+#include <mesh/tnlGrid.h>
+#include <core/tnlDevice.h>
+#include <time.h>
+#include <ctime>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+	time_t start;
+	time_t stop;
+	time(&start);
+	std::clock_t start2= std::clock();
+	Config::ParameterContainer parameters;
+	tnlConfigDescription configDescription;
+	parallelMapConfig< BuildConfig >::configSetup( configDescription );
+
+	if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
+	  return false;
+
+
+	tnlDeviceEnum device;
+	device = TNL::Devices::HostDevice;
+
+	const int& dim = parameters.getParameter< int >( "dim" );
+
+	if(dim == 2)
+	{
+
+	   typedef parallelGodunovMapScheme< tnlGrid<2,double,TNL::Devices::Host, int>, double, int > SchemeTypeHost;
+/*#ifdef HAVE_CUDA
+		   typedef parallelGodunovMapScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice;
+#endif
+#ifndef HAVE_CUDA*/
+	   typedef parallelGodunovMapScheme< tnlGrid<2,double,TNL::Devices::Host, int>, double, int > SchemeTypeDevice;
+/*#endif*/
+
+	   if(device==TNL::Devices::HostDevice)
+	   {
+		   typedef TNL::Devices::Host Device;
+
+
+		   tnlParallelMapSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+	   else if(device==tnlCudaDevice )
+	   {
+		   typedef tnlCuda Device;
+//typedef parallelGodunovMapScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType;
+
+		   tnlParallelMapSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+	}
+
+
+	time(&stop);
+	cout << endl;
+	cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl;
+	return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png
new file mode 100644
index 0000000000000000000000000000000000000000..668b6fe24b17b2fec486db28505b41e3beb2091a
Binary files /dev/null and b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png differ
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bfdc1ef236ca02ecfe6bc88f81d872e9524ec621
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile
@@ -0,0 +1,41 @@
+TNL_VERSION=0.1
+TNL_INSTALL_DIR=${HOME}/local/lib
+TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION}
+
+TARGET = hamiltonJacobiParallelSolver
+#CONFIG_FILE = $(TARGET).cfg.desc
+INSTALL_DIR = ${HOME}/local
+CXX = g++
+CUDA_CXX = nvcc
+OMP_FLAGS = -DHAVE_OPENMP -fopenmp
+CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) -DDEBUG
+LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp
+
+SOURCES = main.cpp
+HEADERS = 
+OBJECTS = main.o
+DIST = $(SOURCES) Makefile
+
+all: $(TARGET)
+clean: 
+	rm -f $(OBJECTS)
+	rm -f $(TARGET)-conf.h	
+
+dist: $(DIST)
+	tar zcvf $(TARGET).tgz $(DIST) 
+
+install: $(TARGET)
+	cp $(TARGET) $(INSTALL_DIR)/bin
+	cp $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+uninstall: $(TARGET)
+	rm -f $(INSTALL_DIR)/bin/$(TARGET) 
+	rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+$(TARGET): $(OBJECTS)
+	$(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS)
+
+%.o: %.cpp $(HEADERS)
+	$(CXX) -c -o $@ $(CXX_FLAGS) $<
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..c07ee95aa04bb8c7a1f3cc376aabd859ff7bc5be
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+                          parallelMapConfig.h  -  description
+                             -------------------
+    begin                : Mar 22 , 2016
+    copyright            : (C) 2016 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_
+#define HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class parallelMapConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Parallel Eikonal solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi-parallel" );
+         config.addEntry       < String > ( "scheme", "This defines scheme used for discretization.", "godunov" );
+         config.addEntryEnum( "godunov" );
+         config.addEntryEnum( "upwind" );
+         config.addRequiredEntry        < String > ( "initial-condition", "Initial condition for solver");
+         config.addRequiredEntry        < String > ( "map", "Gradient map for solver");
+         config.addEntry       < String > ( "mesh", "Name of mesh.", "mesh.tnl" );
+         config.addEntry        < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 0.0 );
+         config.addEntry        < double > ( "delta", " Allowed difference on subgrid boundaries", 0.0 );
+         config.addRequiredEntry        < double > ( "stop-time", " Final time for solver");
+         config.addRequiredEntry        < double > ( "initial-tau", " initial tau for solver" );
+         config.addEntry        < double > ( "cfl-condition", " CFL condition", 0.0 );
+         config.addEntry        < int > ( "subgrid-size", "Subgrid size.", 16 );
+         config.addRequiredEntry        < int > ( "dim", "Dimension of problem.");
+      }
+};
+
+#endif /* HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run
new file mode 100755
index 0000000000000000000000000000000000000000..48441996274633f8d391d9b32978b05b2e4fa263
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+dimensions=2
+
+size=2
+
+time=50
+
+rm -r work_dir
+mkdir work_dir
+cp mapa_png.png work_dir/mapa_png.png
+cd  work_dir
+
+tnl-image-converter 		--image-format png\
+		    		--input-images mapa_png.png
+
+
+tnl-init 			--test-function sdf-para \
+	     			--x-centre 0.5 \
+	    			--y-centre 1.0 \
+ 	   			--offset 0.05 \
+           			--output-file init.tnl \
+	     			--final-time 0.0 \
+	     			--snapshot-period 0.1
+
+hamilton-jacobi-parallel-map-dbg 	--initial-condition init.tnl \
+				--map mapa_png.tnl \
+              			--cfl-condition 50 \
+	      	  		--mesh mesh.tnl \
+	     	  		--initial-tau 1.0e-3 \
+	      	  		--epsilon 4.0 \
+        	  		--delta 0.0 \
+       	      			--stop-time $time \
+	          		--scheme godunov \
+	          		--subgrid-size 8 \
+		  		--dim $dimensions
+
+	
+#cp ../template.dat1 template.dat1
+#cp ../template.dat2 template.dat2
+#cp ../gplt2eps.py gplt2eps.py
+cd ..
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py
new file mode 100755
index 0000000000000000000000000000000000000000..f8cde3768e9b76156507e133f8bc3ecaa526fc71
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+import sys, string, math
+
+arguments = sys. argv[1:]
+format = "txt"
+output_file_name = "eoc-table.txt"
+input_files = []
+verbose = 1
+size = 1.0
+
+i = 0
+while i < len( arguments ):
+   if arguments[ i ] == "--format":
+      format = arguments[ i + 1 ]
+      i = i + 2
+      continue
+   if arguments[ i ] == "--output-file":
+      output_file_name = arguments[ i + 1 ]
+      i = i + 2
+      continue
+   if arguments[ i ] == "--verbose":
+       verbose = float( arguments[ i + 1 ] )
+       i = i +2
+       continue
+   if arguments[ i ] == "--size":
+       size = float( arguments[ i + 1 ] )
+       i = i +2
+       continue
+   input_files. append( arguments[ i ] )
+   i = i + 1
+
+if not verbose == 0:
+   print "Writing to " + output_file_name + " in " + format + "."
+
+h_list = []
+l1_norm_list = []
+l2_norm_list = []
+max_norm_list = []
+items = 0
+
+for file_name in input_files:
+   if not verbose == 0:
+       print "Processing file " + file_name
+   file = open( file_name, "r" )
+   
+   l1_max = 0.0
+   l_max_max = 0.0
+   file.readline();
+   file.readline();
+   for line in file. readlines():
+         data = string. split( line )
+         h_list. append( size/(float(file_name[0:len(file_name)-5] ) - 1.0) )
+         l1_norm_list. append( float( data[ 1 ] ) )
+         l2_norm_list. append( float( data[ 2 ] ) )
+         max_norm_list. append( float( data[ 3 ] ) )
+         items = items + 1
+         if not verbose == 0:
+            print line
+   file. close()
+
+h_width = 12
+err_width = 15
+file = open( output_file_name, "w" )
+if format == "latex":
+      file. write( "\\begin{tabular}{|r|l|l|l|l|l|l|}\\hline\n" )
+      file. write( "\\raisebox{-1ex}[0ex]{$h$}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_1\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_2\\left(\\omega_h;\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_\\infty\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}\\\\ \\cline{2-7} \n" )
+      file. write( " " + string. rjust( " ", h_width ) + "&" +
+                string. rjust( "Error", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) + "&" +
+                string. rjust( "Error", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) + "&" +
+                string. rjust( "Error.", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) +
+                "\\\\ \\hline \\hline \n")
+if format == "txt":
+    file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+    file. write( "|       h      |     L1 Err.    |     L1 EOC.    |     L2 Err.    |      L2 EOC    |    MAX Err.    |     MAX EOC    |\n" )
+    file. write( "+==============+================+================+================+================+================+================+\n" )
+                  
+
+i = 0
+while i < items:
+   if i == 0:
+      if format == "latex":
+         file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + 
+                      string. rjust( " ", err_width ) + "&"+ 
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( " ", err_width ) + "&" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( " ", err_width ) + "\\\\\n" )
+      if format == "txt":
+         file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + 
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |\n" )
+         file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+      i = i + 1;
+      continue
+   if h_list[ i ] == h_list[ i - 1 ]:
+      print "Unable to count eoc since h[ " + \
+      str( i ) + " ] = h[ " + str( i - 1 ) + \
+      " ] = " + str( h_list[ i ] ) + ". \n"
+      file. write( " eoc error:  h[ " + \
+      str( i ) + " ] = h[ " + str( i - 1 ) + \
+      " ] = " + str( h_list[ i ] ) + ". \n" )
+   else:
+      h_ratio = math. log( h_list[ i ] / h_list[ i - 1 ] )
+      l1_ratio = math. log( l1_norm_list[ i ] / l1_norm_list[ i - 1 ] )
+      l2_ratio = math. log( l2_norm_list[ i ] / l2_norm_list[ i - 1 ] )
+      max_ratio = math. log( max_norm_list[ i ] / max_norm_list[ i - 1 ] )
+      if format == "latex":
+         file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( l1_ratio / h_ratio ) + "}", err_width ) + "&" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( l2_ratio / h_ratio ) + "}", err_width ) + "&" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( max_ratio / h_ratio ) + "}", err_width ) + "\\\\\n" )
+      if format == "txt":
+         file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( l1_ratio / h_ratio ) + "**", err_width ) + " |" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( l2_ratio / h_ratio ) + "**", err_width ) + " |" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( max_ratio / h_ratio ) + "**", err_width ) + " |\n" )
+         file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+   i = i + 1
+
+if format == "latex":
+   file. write( "\\hline \n" )
+   file. write( "\\end{tabular} \n" )
+    
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..400e163c9dcc8d536a478a0952aabf8ccbb1a2d8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
@@ -0,0 +1,217 @@
+/***************************************************************************
+                          tnlParallelMapSolver.h  -  description
+                             -------------------
+    begin                : Mar 22 , 2016
+    copyright            : (C) 2016 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLPARALLELMAPSOLVER_H_
+#define TNLPARALLELMAPSOLVER_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+
+
+#include <ctime>
+
+#ifdef HAVE_CUDA
+#include <core/tnlCuda.h>
+#endif
+
+
+template< int Dimension,
+		  typename SchemeHost,
+		  typename SchemeDevice,
+		  typename Device,
+		  typename RealType = double,
+          typename IndexType = int >
+class tnlParallelMapSolver
+{};
+
+template<typename SchemeHost, typename SchemeDevice, typename Device>
+class tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >
+{
+public:
+
+	typedef SchemeDevice SchemeTypeDevice;
+	typedef SchemeHost SchemeTypeHost;
+	typedef Device DeviceType;
+	typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorType;
+	typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorType;
+	typedef tnlGrid< 2, double, TNL::Devices::Host, int > MeshType;
+#ifdef HAVE_CUDA
+	typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorTypeCUDA;
+	typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorTypeCUDA;
+	typedef tnlGrid< 2, double, TNL::Devices::Host, int > MeshTypeCUDA;
+#endif
+	tnlParallelMapSolver();
+	bool init( const Config::ParameterContainer& parameters );
+	void run();
+
+	void test();
+
+/*private:*/
+
+
+	void synchronize();
+
+	int getOwner( int i) const;
+
+	int getSubgridValue( int i ) const;
+
+	void setSubgridValue( int i, int value );
+
+	int getBoundaryCondition( int i ) const;
+
+	void setBoundaryCondition( int i, int value );
+
+	void stretchGrid();
+
+	void contractGrid();
+
+	VectorType getSubgrid( const int i ) const;
+
+	void insertSubgrid( VectorType u, const int i );
+
+	VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID,VectorType map);
+
+
+	tnlMeshFunction<MeshType> u0;
+	VectorType work_u, map_stretched, map;
+	IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount;
+	MeshType mesh, subMesh;
+
+//	tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity;
+
+	SchemeHost schemeHost;
+	SchemeDevice schemeDevice;
+	double delta, tau0, stopTime,cflCondition;
+	int gridRows, gridCols, gridLevels, currentStep, n;
+
+	std::clock_t start;
+	double time_diff;
+
+
+	tnlDeviceEnum device;
+
+	tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* getSelf()
+	{
+		return this;
+	};
+
+#ifdef HAVE_CUDA
+
+	tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver;
+
+	double* work_u_cuda;
+	double* map_stretched_cuda;
+
+	int* subgridValues_cuda;
+	int* boundaryConditions_cuda;
+	int* unusedCell_cuda;
+	int* calculationsCount_cuda;
+	double* tmpw;
+	double* tmp_map;
+
+
+	int* runcuda;
+	int run_host;
+
+
+	__device__ void getSubgridCUDA2D( const int i, tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void updateSubgridCUDA2D( const int i, tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void insertSubgridCUDA2D( double u, const int i );
+
+	__device__ void runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID);
+
+	__device__ int getOwnerCUDA2D( int i) const;
+
+	__device__ int getSubgridValueCUDA2D( int i ) const;
+
+	__device__ void setSubgridValueCUDA2D( int i, int value );
+
+	__device__ int getBoundaryConditionCUDA2D( int i ) const;
+
+	__device__ void setBoundaryConditionCUDA2D( int i, int value );
+
+#endif
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef HAVE_CUDA
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void runCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initRunCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initCUDA2D( tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3, double* tmp_map_ptr);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronizeCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronize2CUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+
+
+__device__
+double fabsMin( double x, double y)
+{
+	double fx = abs(x);
+
+	if(Min(fx,abs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__device__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+#endif
+
+#include "tnlParallelMapSolver2D_impl.h"
+#endif /* TNLPARALLELMAPSOLVER_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2925df8b236f13b0d3c460b5ca9b2970ff730e80
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h
@@ -0,0 +1,1315 @@
+/***************************************************************************
+                          tnlParallelMapSolver2D_impl.h  -  description
+                             -------------------
+    begin                : Mar 22 , 2016
+    copyright            : (C) 2016 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLPARALLELMAPSOLVER2D_IMPL_H_
+#define TNLPARALLELMAPSOLVER2D_IMPL_H_
+
+
+#include "tnlParallelMapSolver.h"
+#include <core/mfilename.h>
+
+
+
+
+#define MAP_SOLVER_MAX_VALUE 3
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelMapSolver()
+{
+	this->device = TNL::Devices::HostDevice;  /////////////// tnlCuda Device --- vypocet na GPU, TNL::Devices::HostDevice   ---    vypocet na CPU
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+	run_host = 1;
+	}
+#endif
+
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::test()
+{
+/*
+	for(int i =0; i < this->subgridValues.getSize(); i++ )
+	{
+		insertSubgrid(getSubgrid(i), i);
+	}
+*/
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+
+bool tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters )
+{
+	cout << "Initializating solver..." << endl;
+	const String& meshLocation = parameters.getParameter <String>("mesh");
+	this->mesh.load( meshLocation );
+
+	this->n = parameters.getParameter <int>("subgrid-size");
+	cout << "Setting N to " << this->n << endl;
+
+	this->subMesh.setDimensions( this->n, this->n );
+	this->subMesh.setDomain( Containers::StaticVector<2,double>(0.0, 0.0),
+							 Containers::StaticVector<2,double>(mesh.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n)) );
+
+	this->subMesh.save("submesh.tnl");
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	this->u0.load( initialCondition );
+
+	/* LOAD MAP */
+	const String& mapFile = parameters.getParameter <String>("map");
+	if(! this->map.load( mapFile ))
+		cout << "Failed to load map file : " << mapFile << endl;
+
+
+	this->delta = parameters.getParameter <double>("delta");
+	this->delta *= mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >();
+
+	cout << "Setting delta to " << this->delta << endl;
+
+	this->tau0 = parameters.getParameter <double>("initial-tau");
+	cout << "Setting initial tau to " << this->tau0 << endl;
+	this->stopTime = parameters.getParameter <double>("stop-time");
+
+	this->cflCondition = parameters.getParameter <double>("cfl-condition");
+	this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >());
+	cout << "Setting CFL to " << this->cflCondition << endl;
+
+	stretchGrid();
+	this->stopTime /= (double)(this->gridCols);
+	this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0));
+	cout << "Setting stopping time to " << this->stopTime << endl;
+
+	cout << "Initializating scheme..." << endl;
+	if(!this->schemeHost.init(parameters))
+	{
+		cerr << "SchemeHost failed to initialize." << endl;
+		return false;
+	}
+	cout << "Scheme initialized." << endl;
+
+	test();
+
+	VectorType* tmp = new VectorType[subgridValues.getSize()];
+	bool containsCurve = false;
+
+#ifdef HAVE_CUDA
+
+	if(this->device == tnlCudaDevice)
+	{
+		cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >));
+		cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice);
+
+		double** tmpdev = NULL;
+		cudaMalloc(&tmpdev, sizeof(double*));
+		cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double));
+		cudaMalloc(&(this->tmp_map), this->map_stretched.getSize()*sizeof(double));
+		cudaMalloc(&(this->runcuda), sizeof(int));
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		int* tmpUC;
+		cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int));
+		cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice);
+
+		initCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC, tmp_map);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		double* tmpu = NULL;
+		cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost);
+		cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+		cudaMemcpy((this->tmp_map), this->map_stretched.getData(), this->map_stretched.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+	}
+#endif
+
+	if(this->device == TNL::Devices::HostDevice)
+	{
+		VectorType tmp_map;
+		tmp_map.setSize(this->n * this->n);
+		for(int i = 0; i < this->subgridValues.getSize(); i++)
+		{
+
+			if(! tmp[i].setSize(this->n * this->n))
+				cout << "Could not allocate tmp["<< i <<"] array." << endl;
+				tmp[i] = getSubgrid(i);
+			containsCurve = false;
+
+			for(int j = 0; j < tmp[i].getSize(); j++)
+			{
+				if(tmp[i][0]*tmp[i][j] <= 0.0)
+				{
+					containsCurve = true;
+					j=tmp[i].getSize();
+				}
+
+			}
+			if(containsCurve)
+			{
+				for( int j = 0; j < tmp_map.getSize(); j++)
+				{
+					tmp_map[j] = this->map_stretched[ (i / this->gridCols) * this->n*this->n*this->gridCols
+										 + (i % this->gridCols) * this->n
+										 + (j/this->n) * this->n*this->gridCols
+										 + (j % this->n) ];
+				}
+				//cout << "Computing initial SDF on subgrid " << i << "." << endl;
+				tmp[i] = runSubgrid(0, tmp[i],i,tmp_map);
+				insertSubgrid(tmp[i], i);
+				setSubgridValue(i, 4);
+				//cout << "Computed initial SDF on subgrid " << i  << "." << endl;
+			}
+			containsCurve = false;
+
+		}
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		initRunCUDA2D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+	}
+#endif
+
+
+	this->currentStep = 1;
+	if(this->device == TNL::Devices::HostDevice)
+		synchronize();
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+
+		synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+	}
+
+#endif
+	cout << "Solver initialized." << endl;
+
+	return true;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::run()
+{
+	if(this->device == TNL::Devices::HostDevice)
+	{
+		while ((this->boundaryConditions.max() > 0 )/* || !end*/)
+		{
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for num_threads(4) schedule(dynamic)
+#endif
+			for(int i = 0; i < this->subgridValues.getSize(); i++)
+			{
+				if(getSubgridValue(i) != INT_MAX)
+				{
+					VectorType tmp, tmp_map;
+					tmp.setSize(this->n * this->n);
+					tmp_map.setSize(this->n * this->n);
+					for( int j = 0; j < tmp_map.getSize(); j++)
+					{
+						tmp_map[j] = this->map_stretched[ (i / this->gridCols) * this->n*this->n*this->gridCols
+											 + (i % this->gridCols) * this->n
+											 + (j/this->n) * this->n*this->gridCols
+											 + (j % this->n) ];
+					}
+
+					if(getSubgridValue(i) == currentStep+4)
+					{
+
+						if(getBoundaryCondition(i) & 1)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(1, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) & 2)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(2, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) & 4)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(4, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) & 8)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(8, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+					}
+					else
+					{
+
+						if(getBoundaryCondition(i) == 1)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(1, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) == 2)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(2, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) == 4)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(4, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+						if(getBoundaryCondition(i) == 8)
+						{
+							tmp = getSubgrid(i);
+							tmp = runSubgrid(8, tmp ,i,tmp_map);
+							insertSubgrid( tmp, i);
+							this->calculationsCount[i]++;
+						}
+					}
+
+					if(getBoundaryCondition(i) & 3)
+					{
+						//cout << "3 @ " << getBoundaryCondition(i) << endl;
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(3, tmp ,i,tmp_map);
+						insertSubgrid( tmp, i);
+					}
+					if(getBoundaryCondition(i) & 5)
+					{
+						//cout << "5 @ " << getBoundaryCondition(i) << endl;
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(5, tmp ,i,tmp_map);
+						insertSubgrid( tmp, i);
+					}
+					if(getBoundaryCondition(i) & 10)
+					{
+						//cout << "10 @ " << getBoundaryCondition(i) << endl;
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(10, tmp ,i,tmp_map);
+						insertSubgrid( tmp, i);
+					}
+					if(getBoundaryCondition(i) & 12)
+					{
+						//cout << "12 @ " << getBoundaryCondition(i) << endl;
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(12, tmp ,i,tmp_map);
+						insertSubgrid( tmp, i);
+					}
+
+
+					setBoundaryCondition(i, 0);
+
+					setSubgridValue(i, getSubgridValue(i)-1);
+
+				}
+			}
+			synchronize();
+		}
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		bool end_cuda = false;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		bool* tmpb;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+
+		int i = 1;
+		time_diff = 0.0;
+		while (run_host || !end_cuda)
+		{
+			cout << "Computing at step "<< i++ << endl;
+			if(run_host != 0 )
+				end_cuda = true;
+			else
+				end_cuda = false;
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			start = std::clock();
+			runCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+			//start = std::clock();
+			synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			//time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+			cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost);
+		}
+		cout << "Solving time was: " << time_diff << endl;
+
+		cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+
+		cudaDeviceSynchronize();
+	}
+#endif
+	contractGrid();
+	this->u0.save("u-00001.tnl");
+	cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl;
+	cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl;
+	cout << "Solver finished" << endl;
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+		cudaFree(this->runcuda);
+		cudaFree(this->tmpw);
+		cudaFree(this->tmp_map);
+		cudaFree(this->cudaSolver);
+	}
+#endif
+
+}
+
+//north - 1, east - 2, west - 4, south - 8
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+	cout << "Synchronizig..." << endl;
+	int tmp1, tmp2;
+	int grid1, grid2;
+
+//	if(this->currentStep & 1)
+//	{
+		for(int j = 0; j < this->gridRows - 1; j++)
+		{
+			for (int i = 0; i < this->gridCols*this->n; i++)
+			{
+				tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i;
+				tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i;
+				grid1 = getSubgridValue(getOwner(tmp1));
+				grid2 = getSubgridValue(getOwner(tmp2));
+				if(getOwner(tmp1)==getOwner(tmp2))
+					cout << "i, j" << i << "," << j << endl;
+				if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					this->work_u[tmp2] = this->work_u[tmp1];
+					this->unusedCell[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp2), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp2)) & 8) )
+						setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8);
+				}
+				else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					this->work_u[tmp1] = this->work_u[tmp2];
+					this->unusedCell[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp1), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp1)) & 1) )
+						setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1);
+				}
+			}
+		}
+
+//	}
+//	else
+//	{
+		for(int i = 1; i < this->gridCols; i++)
+		{
+			for (int j = 0; j < this->gridRows*this->n; j++)
+			{
+				tmp1 = this->gridCols*this->n*j + i*this->n - 1;
+				tmp2 = this->gridCols*this->n*j + i*this->n ;
+				grid1 = getSubgridValue(getOwner(tmp1));
+				grid2 = getSubgridValue(getOwner(tmp2));
+				if(getOwner(tmp1)==getOwner(tmp2))
+					cout << "i, j" << i << "," << j << endl;
+				if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					this->work_u[tmp2] = this->work_u[tmp1];
+					this->unusedCell[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp2), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp2)) & 4) )
+						setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4);
+				}
+				else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					this->work_u[tmp1] = this->work_u[tmp2];
+					this->unusedCell[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp1), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp1)) & 2) )
+						setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2);
+				}
+			}
+		}
+//	}
+
+
+	this->currentStep++;
+	int stepValue = this->currentStep + 4;
+	for (int i = 0; i < this->subgridValues.getSize(); i++)
+	{
+		if( getSubgridValue(i) == -INT_MAX )
+			setSubgridValue(i, stepValue);
+	}
+
+	cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl;
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const
+{
+
+	return (i / (this->gridCols*this->n*this->n))*this->gridCols + (i % (this->gridCols*this->n))/this->n;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const
+{
+	return this->subgridValues[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value)
+{
+	this->subgridValues[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const
+{
+	return this->boundaryConditions[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value)
+{
+	this->boundaryConditions[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid()
+{
+	cout << "Stretching grid..." << endl;
+
+
+	this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) );
+	this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) );
+
+
+	cout << "Setting gridCols to " << this->gridCols << "." << endl;
+	cout << "Setting gridRows to " << this->gridRows << "." << endl;
+
+	this->subgridValues.setSize(this->gridCols*this->gridRows);
+	this->subgridValues.setValue(0);
+	this->boundaryConditions.setSize(this->gridCols*this->gridRows);
+	this->boundaryConditions.setValue(0);
+	this->calculationsCount.setSize(this->gridCols*this->gridRows);
+	this->calculationsCount.setValue(0);
+
+	for(int i = 0; i < this->subgridValues.getSize(); i++ )
+	{
+		this->subgridValues[i] = INT_MAX;
+		this->boundaryConditions[i] = 0;
+	}
+
+	int stretchedSize = this->n*this->n*this->gridCols*this->gridRows;
+
+	if(!this->work_u.setSize(stretchedSize))
+		cerr << "Could not allocate memory for stretched grid." << endl;
+	if(!this->map_stretched.setSize(stretchedSize))
+		cerr << "Could not allocate memory for stretched map." << endl;
+	if(!this->unusedCell.setSize(stretchedSize))
+		cerr << "Could not allocate memory for supporting stretched grid." << endl;
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+	for(int i = 0; i < stretchedSize; i++)
+	{
+		this->unusedCell[i] = 1;
+		int diff =(this->n*this->gridCols) - idealStretch ;
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if(i%(this->n*this->gridCols) - idealStretch  >= 0)
+		{
+			k+= i%(this->n*this->gridCols) - idealStretch +1 ;
+		}
+
+		if(i/(this->n*this->gridCols) - idealStretch + 1  > 0)
+		{
+			k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ;
+		}
+
+
+		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;
+
+		this->map_stretched[i] = this->map[i-k];
+	}
+
+
+	cout << "Grid stretched." << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::contractGrid()
+{
+	cout << "Contracting grid..." << endl;
+	int stretchedSize = this->n*this->n*this->gridCols*this->gridRows;
+
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+	for(int i = 0; i < stretchedSize; i++)
+	{
+		int diff =(this->n*this->gridCols) - idealStretch ;
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if((i%(this->n*this->gridCols) - idealStretch  < 0) && (i/(this->n*this->gridCols) - idealStretch + 1  <= 0))
+		{
+			this->u0[i-k] = this->work_u[i];
+		}
+
+	}
+
+	cout << "Grid contracted" << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const
+{
+	VectorType u;
+	u.setSize(this->n*this->n);
+
+	for( int j = 0; j < u.getSize(); j++)
+	{
+		u[j] = this->work_u[ (i / this->gridCols) * this->n*this->n*this->gridCols
+		                     + (i % this->gridCols) * this->n
+		                     + (j/this->n) * this->n*this->gridCols
+		                     + (j % this->n) ];
+	}
+	return u;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i )
+{
+
+	for( int j = 0; j < this->n*this->n; j++)
+	{
+		int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n);
+		if( (fabs(this->work_u[index]) > fabs(u[j])) || (this->unusedCell[index] == 1) )
+		{
+			this->work_u[index] = u[j];
+			this->unusedCell[index] = 0;
+		}
+	}
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID,VectorType map)
+{
+
+	VectorType fu;
+
+	fu.setLike(u);
+	fu.setValue( 0.0 );
+
+
+
+	bool tmp = false;
+	for(int i = 0; i < u.getSize(); i++)
+	{
+		if(u[0]*u[i] <= 0.0)
+			tmp=true;
+		int centerGID = (this->n*(subGridID / this->gridRows)+ (this->n >> 1))*(this->n*this->gridCols) + this->n*(subGridID % this->gridRows) + (this->n >> 1);
+		if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0)
+			tmp = true;
+	}
+
+
+	double value = sign(u[0]) * u.absMax();
+
+	if(tmp)
+	{}
+
+
+	//north - 1, east - 2, west - 4, south - 8
+	else if(boundaryCondition == 4)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j = 1;j < this->n; j++)
+				//if(fabs(u[i*this->n + j]) <  fabs(u[i*this->n]))
+				u[i*this->n + j] = value;// u[i*this->n];
+	}
+	else if(boundaryCondition == 2)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j =0 ;j < this->n -1; j++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1]))
+				u[i*this->n + j] = value;// u[(i+1)*this->n - 1];
+	}
+	else if(boundaryCondition == 1)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 0;i < this->n - 1; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)]))
+				u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)];
+	}
+	else if(boundaryCondition == 8)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 1;i < this->n; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j]))
+				u[i*this->n + j] = value;// u[j];
+	}
+
+
+
+   double time = 0.0;
+   double currentTau = this->tau0;
+   double finalTime = this->stopTime;// + 3.0*(u.max() - u.min());
+   if( time + currentTau > finalTime ) currentTau = finalTime - time;
+
+   double maxResidue( 1.0 );
+   tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+
+   for( int i = 0; i < u.getSize(); i ++ )
+   {
+		if(map[i] == 0.0)
+		{
+			u[i] = /*sign(u[l])**/MAP_SOLVER_MAX_VALUE;
+		}
+   }
+
+   while( time < finalTime )
+   {
+      /****
+       * Compute the RHS
+       */
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+			Entity.setCoordinates(Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()));
+			Entity.refresh();
+			neighborEntities.refresh(subMesh,Entity.getIndex());
+			if(map[i] != 0.0)
+				fu[ i ] = schemeHost.getValue( this->subMesh, i, Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()), u, time, boundaryCondition,neighborEntities,map);
+      }
+      maxResidue = fu. absMax();
+
+
+      if(maxResidue != 0.0)
+    	  currentTau =  fabs(this -> cflCondition / maxResidue);
+
+
+      if(currentTau > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >())
+      {
+    	  currentTau = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >();
+      }
+
+
+      if( time + currentTau > finalTime ) currentTau = finalTime - time;
+
+
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+    	  if(map[i] != 0.0)
+    		  u[ i ] += currentTau * fu[ i ];
+      }
+      time += currentTau;
+
+   }
+   return u;
+}
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA2D( const int i ,tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+	int th = (blockIdx.y) * caller->n*caller->n*caller->gridCols
+            + (blockIdx.x) * caller->n
+            + threadIdx.y * caller->n*caller->gridCols
+            + threadIdx.x;
+
+	*a = caller->work_u_cuda[th];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA2D( const int i ,tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+	int index = (blockIdx.y) * caller->n*caller->n*caller->gridCols
+            + (blockIdx.x) * caller->n
+            + threadIdx.y * caller->n*caller->gridCols
+            + threadIdx.x;
+
+	if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) )
+	{
+		caller->work_u_cuda[index] = *a;
+		caller->unusedCell_cuda[index] = 0;
+
+	}
+
+	*a = caller->work_u_cuda[index];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA2D( double u, const int i )
+{
+		int index = (blockIdx.y)*this->n*this->n*this->gridCols
+					+ (blockIdx.x)*this->n
+					+ threadIdx.y*this->n*this->gridCols
+					+ threadIdx.x;
+
+		if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) )
+		{
+			this->work_u_cuda[index] = u;
+			this->unusedCell_cuda[index] = 0;
+
+		}
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID)
+{
+
+	__shared__ int tmp;
+	__shared__ double value;
+	volatile double* sharedTau = &u[blockDim.x*blockDim.y];
+	double* map_local = &u[2*blockDim.x*blockDim.y];
+
+	int i = threadIdx.x;
+	int j = threadIdx.y;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x;
+
+	/* LOAD MAP */
+	map_local[l]=this->map_stretched_cuda[gid];
+	if(map_local[l] != 0.0)
+		map_local[l] = 1.0/map_local[l];
+	/* LOADED */
+
+	bool computeFU = !((i == 0 && (boundaryCondition & 4)) or
+			 (i == blockDim.x - 1 && (boundaryCondition & 2)) or
+			 (j == 0 && (boundaryCondition & 8)) or
+			 (j == blockDim.y - 1  && (boundaryCondition & 1)));
+
+	if(l == 0)
+	{
+		tmp = 0;
+		int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1))*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1);
+		if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0)
+			tmp = 1;
+	}
+	__syncthreads();
+
+
+	if(tmp !=1)
+	{
+		if(computeFU)
+		{
+			if(boundaryCondition == 4)
+				u[l] = u[threadIdx.y * blockDim.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x);
+			else if(boundaryCondition == 2)
+				u[l] = u[threadIdx.y * blockDim.x + blockDim.x - 1] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.x);
+			else if(boundaryCondition == 8)
+				u[l] = u[threadIdx.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y);
+			else if(boundaryCondition == 1)
+				u[l] = u[(blockDim.y - 1)* blockDim.x + threadIdx.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.y);
+		}
+	}
+
+   double time = 0.0;
+   __shared__ double currentTau;
+   double cfl = this->cflCondition;
+   double fu = 0.0;
+
+   double finalTime = this->stopTime;
+   if(boundaryCondition == 0)
+	   finalTime*=2.0;
+   __syncthreads();
+
+   tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<2,int>(i,j));
+   Entity.refresh();
+   neighborEntities.refresh(subMesh,Entity.getIndex());
+
+
+	if(map_local[l] == 0.0)
+	{
+		u[l] = /*sign(u[l])**/MAP_SOLVER_MAX_VALUE;
+		computeFU = false;
+	}
+	__syncthreads();
+
+
+   while( time < finalTime )
+   {
+	  sharedTau[l] = finalTime;
+
+	  if(computeFU)
+	  {
+		  fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<2,int>(i,j), u, time, boundaryCondition, neighborEntities, map_local);
+	  	  sharedTau[l]=abs(cfl/fu);
+	  }
+
+
+
+      if(l == 0)
+      {
+    	  if(sharedTau[0] > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >())	sharedTau[0] = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >();
+      }
+      else if(l == blockDim.x*blockDim.y - 1)
+    	  if( time + sharedTau[l] > finalTime )		sharedTau[l] = finalTime - time;
+
+
+      if((blockDim.x == 16) && (l < 128))		sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]);
+      __syncthreads();
+      if((blockDim.x == 16) && (l < 64))		sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]);
+      __syncthreads();
+      if(l < 32)    							sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]);
+      if(l < 16)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]);
+      if(l < 8)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]);
+      if(l < 4)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]);
+      if(l < 2)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]);
+      if(l < 1)									currentTau   = Min(sharedTau[l],sharedTau[l+1]);
+      __syncthreads();
+
+      u[l] += currentTau * fu;
+      time += currentTau;
+   }
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA2D(int i) const
+{
+
+	return ((i / (this->gridCols*this->n*this->n))*this->gridCols
+			+ (i % (this->gridCols*this->n))/this->n);
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA2D( int i ) const
+{
+	return this->subgridValues_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA2D(int i, int value)
+{
+	this->subgridValues_cuda[i] = value;
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA2D( int i ) const
+{
+	return this->boundaryConditions_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA2D(int i, int value)
+{
+	this->boundaryConditions_cuda[i] = value;
+}
+
+
+
+//north - 1, east - 2, west - 4, south - 8
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void synchronizeCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+
+	__shared__ int boundary[4]; // north,east,west,south
+	__shared__ int subgridValue;
+	__shared__ int newSubgridValue;
+
+
+	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x;
+	double u = cudaSolver->work_u_cuda[gid];
+	double u_cmp;
+	int subgridValue_cmp=INT_MAX;
+	int boundary_index=0;
+
+
+	if(threadIdx.x+threadIdx.y == 0)
+	{
+		subgridValue = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x);
+		boundary[0] = 0;
+		boundary[1] = 0;
+		boundary[2] = 0;
+		boundary[3] = 0;
+		newSubgridValue = 0;
+	}
+	__syncthreads();
+
+
+
+	if(		(threadIdx.x == 0 				 /*	&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == 0 				 /*	&& (cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.x == blockDim.x - 1 	 /*	&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == blockDim.y - 1 	 /*	&& (cudaSolver->currentStep & 1)*/) 		)
+	{
+		if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x - 1);
+			boundary_index = 2;
+		}
+
+		if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x + 1);
+			boundary_index = 1;
+		}
+
+		__threadfence();
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+			u=u_cmp;
+		}
+		__threadfence();
+		if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y - 1)*gridDim.x + blockIdx.x);
+			boundary_index = 3;
+		}
+		if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y + 1)*gridDim.x + blockIdx.x);
+			boundary_index = 0;
+		}
+
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+		}
+	}
+	__threadfence();
+	__syncthreads();
+
+	if(threadIdx.x+threadIdx.y == 0)
+	{
+		if(subgridValue == INT_MAX && newSubgridValue !=0)
+			cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, -INT_MAX);
+
+		cudaSolver->setBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, 	boundary[0] +
+																				2 * boundary[1] +
+																				4 * boundary[2] +
+																				8 * boundary[3]);
+
+
+		if(blockIdx.x+blockIdx.y ==0)
+		{
+			cudaSolver->currentStep += 1;
+			*(cudaSolver->runcuda) = 0;
+		}
+	}
+
+}
+
+
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void synchronize2CUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver)
+{
+
+
+	int stepValue = cudaSolver->currentStep + 4;
+	if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX )
+			cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue);
+
+	atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x));
+}
+
+
+
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void initCUDA2D( tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3, double* tmp_map_ptr)
+{
+
+
+	cudaSolver->work_u_cuda = ptr;
+	cudaSolver->map_stretched_cuda = tmp_map_ptr;
+	cudaSolver->unusedCell_cuda = ptr3;
+	cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int));
+	cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int));
+	cudaSolver->runcuda = ptr2;
+	*(cudaSolver->runcuda) = 1;
+
+/* CHANGED !!!!!! from 1 to 0*/	cudaSolver->currentStep = 0;
+
+	printf("GPU memory allocated.\n");
+
+	for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows; i++)
+	{
+		cudaSolver->subgridValues_cuda[i] = INT_MAX;
+		cudaSolver->boundaryConditions_cuda[i] = 0;
+	}
+
+	printf("GPU memory initialized.\n");
+}
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void initRunCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller)
+
+{
+	extern __shared__ double u[];
+
+	int i = blockIdx.y * gridDim.x + blockIdx.x;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+
+	__shared__ int containsCurve;
+	if(l == 0)
+		containsCurve = 0;
+
+
+	caller->getSubgridCUDA2D(i,caller, &u[l]);
+	__syncthreads();
+
+	if(u[0] * u[l] <= 0.0)
+		atomicMax( &containsCurve, 1);
+
+	__syncthreads();
+	if(containsCurve == 1)
+	{
+		caller->runSubgridCUDA2D(0,u,i);
+		caller->insertSubgridCUDA2D(u[l],i);
+		__syncthreads();
+		if(l == 0)
+			caller->setSubgridValueCUDA2D(i, 4);
+	}
+
+
+}
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void runCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller)
+{
+	extern __shared__ double u[];
+	int i = blockIdx.y * gridDim.x + blockIdx.x;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+	int bound = caller->getBoundaryConditionCUDA2D(i);
+
+	if(caller->getSubgridValueCUDA2D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA2D(i) > 0)
+	{
+		caller->getSubgridCUDA2D(i,caller, &u[l]);
+
+
+		if(caller->getSubgridValueCUDA2D(i) == caller->currentStep+4)
+		{
+			if(bound & 1)
+			{
+				caller->runSubgridCUDA2D(1,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 2)
+			{
+				caller->runSubgridCUDA2D(2,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 4)
+			{
+				caller->runSubgridCUDA2D(4,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 8)
+			{
+				caller->runSubgridCUDA2D(8,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+		}
+		else
+		{
+
+			if(bound == 1)
+			{
+				caller->runSubgridCUDA2D(1,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound == 2)
+			{
+				caller->runSubgridCUDA2D(2,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound == 4)
+			{
+				caller->runSubgridCUDA2D(4,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound == 8)
+			{
+				caller->runSubgridCUDA2D(8,u,i);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+		}
+
+		if(bound & 3)
+		{
+			caller->runSubgridCUDA2D(3,u,i);
+			caller->updateSubgridCUDA2D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if(bound & 5)
+		{
+			caller->runSubgridCUDA2D(5,u,i);
+			caller->updateSubgridCUDA2D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if(bound & 10)
+		{
+			caller->runSubgridCUDA2D(10,u,i);
+			caller->updateSubgridCUDA2D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if(bound & 12)
+		{
+			caller->runSubgridCUDA2D(12,u,i);
+			caller->updateSubgridCUDA2D(i,caller, &u[l]);
+			__syncthreads();
+		}
+
+
+		if(l==0)
+		{
+			caller->setBoundaryConditionCUDA2D(i, 0);
+			caller->setSubgridValueCUDA2D(i, caller->getSubgridValueCUDA2D(i) - 1 );
+		}
+
+
+	}
+
+
+
+}
+
+#endif /*HAVE_CUDA*/
+
+#endif /* TNLPARALLELMAPSOLVER2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b65f3e6a4c8d0cc22a5e10dc46f298fcc5e0dfc0
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt
@@ -0,0 +1,23 @@
+set( tnl_hamilton_jacobi_parallel_SOURCES
+#     MainBuildConfig.h
+#     tnlParallelEikonalSolver2D_impl.h
+#     tnlParallelEikonalSolver3D_impl.h
+#     tnlParallelEikonalSolver.h
+#     parallelEikonalConfig.h 
+     main.cpp)
+
+
+IF(  BUILD_CUDA ) 
+	CUDA_ADD_EXECUTABLE(hamilton-jacobi-parallel${debugExt} main.cu)
+ELSE(  BUILD_CUDA )                
+	ADD_EXECUTABLE(hamilton-jacobi-parallel${debugExt} main.cpp)
+ENDIF( BUILD_CUDA )
+target_link_libraries (hamilton-jacobi-parallel${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS hamilton-jacobi-parallel${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+#INSTALL( FILES ${tnl_hamilton_jacobi_parallel_SOURCES}
+#         DESTINATION share/tnl-${tnlVersion}/examples/hamilton-jacobi-parallel )
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b13498e17330fae7bb00a0bdc2abcc7a19f8e7a8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu
new file mode 100644
index 0000000000000000000000000000000000000000..7101976712e153d73c5f0979b211164a36ec648d
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu
@@ -0,0 +1,17 @@
+/***************************************************************************
+                          main.cu  -  description
+                             -------------------
+    begin                : Mar 30 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "main.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h
new file mode 100644
index 0000000000000000000000000000000000000000..178e816aff7c1fe2c46b16529b1b263b24796879
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h
@@ -0,0 +1,142 @@
+/***************************************************************************
+                          main.h  -  description
+                             -------------------
+    begin                : Mar 30 , 2015
+    copyright            : (C) 2015 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "tnlParallelEikonalSolver.h"
+#include "parallelEikonalConfig.h"
+#include "MainBuildConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal.h>
+#include <mesh/tnlGrid.h>
+#include <core/tnlDevice.h>
+#include <time.h>
+#include <ctime>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+	time_t start;
+	time_t stop;
+	time(&start);
+	std::clock_t start2= std::clock();
+   Config::ParameterContainer parameters;
+   tnlConfigDescription configDescription;
+   parallelEikonalConfig< BuildConfig >::configSetup( configDescription );
+
+   if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
+      return false;
+
+   //if (parameters.GetParameter <String>("scheme") == "godunov")
+   //{
+   tnlDeviceEnum device;
+   device = TNL::Devices::HostDevice;
+
+   const int& dim = parameters.getParameter< int >( "dim" );
+
+  if(dim == 2)
+  {
+
+	   typedef parallelGodunovEikonalScheme< tnlGrid<2,double,TNL::Devices::Host, int>, double, int > SchemeTypeHost;
+		/*#ifdef HAVE_CUDA
+		   typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice;
+		#endif
+		#ifndef HAVE_CUDA*/
+	   typedef parallelGodunovEikonalScheme< tnlGrid<2,double,TNL::Devices::Host, int>, double, int > SchemeTypeDevice;
+		/*#endif*/
+
+	   if(device==TNL::Devices::HostDevice)
+	   {
+		   typedef TNL::Devices::Host Device;
+
+
+		   tnlParallelEikonalSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+	   else if(device==tnlCudaDevice )
+	   {
+		   typedef tnlCuda Device;
+		   //typedef parallelGodunovEikonalScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType;
+
+		   tnlParallelEikonalSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+  // }
+  }
+  else if(dim == 3)
+  {
+
+	   typedef parallelGodunovEikonalScheme< tnlGrid<3,double,TNL::Devices::Host, int>, double, int > SchemeTypeHost;
+		/*#ifdef HAVE_CUDA
+		   typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice;
+		#endif
+		#ifndef HAVE_CUDA*/
+	   typedef parallelGodunovEikonalScheme< tnlGrid<3,double,TNL::Devices::Host, int>, double, int > SchemeTypeDevice;
+		/*#endif*/
+
+	   if(device==TNL::Devices::HostDevice)
+	   {
+		   typedef TNL::Devices::Host Device;
+
+
+		   tnlParallelEikonalSolver<3,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+	   else if(device==tnlCudaDevice )
+	   {
+		   typedef tnlCuda Device;
+		   //typedef parallelGodunovEikonalScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType;
+
+		   tnlParallelEikonalSolver<3,SchemeTypeHost,SchemeTypeDevice, Device> solver;
+		   if(!solver.init(parameters))
+		   {
+			   cerr << "Solver failed to initialize." << endl;
+			   return EXIT_FAILURE;
+		   }
+		   cout << "-------------------------------------------------------------" << endl;
+		   cout << "Starting solver loop..." << endl;
+		   solver.run();
+	   }
+ // }
+  }
+
+   time(&stop);
+   cout << endl;
+   cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bfdc1ef236ca02ecfe6bc88f81d872e9524ec621
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile
@@ -0,0 +1,41 @@
+TNL_VERSION=0.1
+TNL_INSTALL_DIR=${HOME}/local/lib
+TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION}
+
+TARGET = hamiltonJacobiParallelSolver
+#CONFIG_FILE = $(TARGET).cfg.desc
+INSTALL_DIR = ${HOME}/local
+CXX = g++
+CUDA_CXX = nvcc
+OMP_FLAGS = -DHAVE_OPENMP -fopenmp
+CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) -DDEBUG
+LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp
+
+SOURCES = main.cpp
+HEADERS = 
+OBJECTS = main.o
+DIST = $(SOURCES) Makefile
+
+all: $(TARGET)
+clean: 
+	rm -f $(OBJECTS)
+	rm -f $(TARGET)-conf.h	
+
+dist: $(DIST)
+	tar zcvf $(TARGET).tgz $(DIST) 
+
+install: $(TARGET)
+	cp $(TARGET) $(INSTALL_DIR)/bin
+	cp $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+uninstall: $(TARGET)
+	rm -f $(INSTALL_DIR)/bin/$(TARGET) 
+	rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+$(TARGET): $(OBJECTS)
+	$(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS)
+
+%.o: %.cpp $(HEADERS)
+	$(CXX) -c -o $@ $(CXX_FLAGS) $<
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..c27f5ebb39e5c4db31ed13d1a8e80b8ca8915d51
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+                          parallelEikonalConfig.h  -  description
+                             -------------------
+    begin                : Oct 5, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_
+#define HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class parallelEikonalConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Parallel Eikonal solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi-parallel" );
+         config.addEntry       < String > ( "scheme", "This defines scheme used for discretization.", "godunov" );
+         config.addEntryEnum( "godunov" );
+         config.addEntryEnum( "upwind" );
+         config.addRequiredEntry        < String > ( "initial-condition", "Initial condition for solver");
+         config.addEntry       < String > ( "mesh", "Name of mesh.", "mesh.tnl" );
+         config.addEntry        < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 0.0 );
+         config.addEntry        < double > ( "delta", " Allowed difference on subgrid boundaries", 0.0 );
+         config.addRequiredEntry        < double > ( "stop-time", " Final time for solver");
+         config.addRequiredEntry        < double > ( "initial-tau", " initial tau for solver" );
+         config.addEntry        < double > ( "cfl-condition", " CFL condition", 0.0 );
+         config.addEntry        < int > ( "subgrid-size", "Subgrid size.", 16 );
+         config.addRequiredEntry        < int > ( "dim", "Dimension of problem.");
+      }
+};
+
+#endif /* HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run
new file mode 100755
index 0000000000000000000000000000000000000000..3aece294a9c1189cd885acbe459dba20be713716
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+#GRID_SIZES="0897"
+GRID_SIZES="0008 0015 0029 0057 0113 0225 0449"
+#GRID_SIZES="1793"
+
+dimensions=2
+
+size=2
+
+time=3
+
+for grid_size in $GRID_SIZES;
+
+do
+
+	rm -r grid-${grid_size}
+   	mkdir grid-${grid_size}
+   	cd grid-${grid_size}
+
+	tnl-grid-setup --dimensions $dimensions \
+	               --origin-x -1.0 \
+	               --origin-y -1.0 \
+	               --origin-z -1.0 \
+	               --proportions-x $size \
+	               --proportions-y $size \
+	               --proportions-z $size \
+	               --size-x ${grid_size} \
+	               --size-y ${grid_size} \
+	               --size-z ${grid_size}
+
+	tnl-init --test-function sdf-para \
+		     --offset 0.25 \
+	             --output-file init.tnl \
+		     --final-time 0.0 \
+		     --snapshot-period 0.1 \
+
+
+	tnl-init --test-function sdf-para-sdf \
+		     --offset 0.25 \
+	             --output-file sdf.tnl \
+		     --final-time 0.0 \
+		     --snapshot-period 0.1
+
+	hamilton-jacobi-parallel --initial-condition init.tnl \
+	              --cfl-condition 1.0e-1 \
+		      	  --mesh mesh.tnl \
+		     	  --initial-tau 1.0e-3 \
+		      	  --epsilon 1.0 \
+	        	  --delta 0.0 \
+	       	      --stop-time $time \
+		          --scheme godunov \
+		          --subgrid-size 8
+
+        tnl-diff --mesh mesh.tnl --mode sequence --input-files sdf.tnl u-00001.tnl --write-difference yes --output-file ../${grid_size}.diff
+	
+	cd ..
+
+done
+
+
+./tnl-err2eoc-2.py --format txt --size $size *.diff
+
+              
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py
new file mode 100755
index 0000000000000000000000000000000000000000..f8cde3768e9b76156507e133f8bc3ecaa526fc71
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+import sys, string, math
+
+arguments = sys. argv[1:]
+format = "txt"
+output_file_name = "eoc-table.txt"
+input_files = []
+verbose = 1
+size = 1.0
+
+i = 0
+while i < len( arguments ):
+   if arguments[ i ] == "--format":
+      format = arguments[ i + 1 ]
+      i = i + 2
+      continue
+   if arguments[ i ] == "--output-file":
+      output_file_name = arguments[ i + 1 ]
+      i = i + 2
+      continue
+   if arguments[ i ] == "--verbose":
+       verbose = float( arguments[ i + 1 ] )
+       i = i +2
+       continue
+   if arguments[ i ] == "--size":
+       size = float( arguments[ i + 1 ] )
+       i = i +2
+       continue
+   input_files. append( arguments[ i ] )
+   i = i + 1
+
+if not verbose == 0:
+   print "Writing to " + output_file_name + " in " + format + "."
+
+h_list = []
+l1_norm_list = []
+l2_norm_list = []
+max_norm_list = []
+items = 0
+
+for file_name in input_files:
+   if not verbose == 0:
+       print "Processing file " + file_name
+   file = open( file_name, "r" )
+   
+   l1_max = 0.0
+   l_max_max = 0.0
+   file.readline();
+   file.readline();
+   for line in file. readlines():
+         data = string. split( line )
+         h_list. append( size/(float(file_name[0:len(file_name)-5] ) - 1.0) )
+         l1_norm_list. append( float( data[ 1 ] ) )
+         l2_norm_list. append( float( data[ 2 ] ) )
+         max_norm_list. append( float( data[ 3 ] ) )
+         items = items + 1
+         if not verbose == 0:
+            print line
+   file. close()
+
+h_width = 12
+err_width = 15
+file = open( output_file_name, "w" )
+if format == "latex":
+      file. write( "\\begin{tabular}{|r|l|l|l|l|l|l|}\\hline\n" )
+      file. write( "\\raisebox{-1ex}[0ex]{$h$}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_1\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_2\\left(\\omega_h;\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" )
+      file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_\\infty\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}\\\\ \\cline{2-7} \n" )
+      file. write( " " + string. rjust( " ", h_width ) + "&" +
+                string. rjust( "Error", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) + "&" +
+                string. rjust( "Error", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) + "&" +
+                string. rjust( "Error.", err_width ) + "&" +
+                string. rjust( "{\\bf EOC}", err_width ) +
+                "\\\\ \\hline \\hline \n")
+if format == "txt":
+    file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+    file. write( "|       h      |     L1 Err.    |     L1 EOC.    |     L2 Err.    |      L2 EOC    |    MAX Err.    |     MAX EOC    |\n" )
+    file. write( "+==============+================+================+================+================+================+================+\n" )
+                  
+
+i = 0
+while i < items:
+   if i == 0:
+      if format == "latex":
+         file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + 
+                      string. rjust( " ", err_width ) + "&"+ 
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( " ", err_width ) + "&" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( " ", err_width ) + "\\\\\n" )
+      if format == "txt":
+         file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + 
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( " ", err_width ) + " |\n" )
+         file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+      i = i + 1;
+      continue
+   if h_list[ i ] == h_list[ i - 1 ]:
+      print "Unable to count eoc since h[ " + \
+      str( i ) + " ] = h[ " + str( i - 1 ) + \
+      " ] = " + str( h_list[ i ] ) + ". \n"
+      file. write( " eoc error:  h[ " + \
+      str( i ) + " ] = h[ " + str( i - 1 ) + \
+      " ] = " + str( h_list[ i ] ) + ". \n" )
+   else:
+      h_ratio = math. log( h_list[ i ] / h_list[ i - 1 ] )
+      l1_ratio = math. log( l1_norm_list[ i ] / l1_norm_list[ i - 1 ] )
+      l2_ratio = math. log( l2_norm_list[ i ] / l2_norm_list[ i - 1 ] )
+      max_ratio = math. log( max_norm_list[ i ] / max_norm_list[ i - 1 ] )
+      if format == "latex":
+         file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( l1_ratio / h_ratio ) + "}", err_width ) + "&" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( l2_ratio / h_ratio ) + "}", err_width ) + "&" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" +
+                      string. rjust( "{\\bf " + "%.2g" % ( max_ratio / h_ratio ) + "}", err_width ) + "\\\\\n" )
+      if format == "txt":
+         file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" +
+                      string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( l1_ratio / h_ratio ) + "**", err_width ) + " |" +
+                      string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( l2_ratio / h_ratio ) + "**", err_width ) + " |" +
+                      string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" +
+                      string. rjust( "**" + "%.2g" % ( max_ratio / h_ratio ) + "**", err_width ) + " |\n" )
+         file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" )
+   i = i + 1
+
+if format == "latex":
+   file. write( "\\hline \n" )
+   file. write( "\\end{tabular} \n" )
+    
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..19cdd949359d4349172af820def49169146c8717
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
@@ -0,0 +1,366 @@
+/***************************************************************************
+                          tnlParallelEikonalSolver.h  -  description
+                             -------------------
+    begin                : Nov 28 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLPARALLELEIKONALSOLVER_H_
+#define TNLPARALLELEIKONALSOLVER_H_
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <TNL/Devices/Host.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+ #include <omp.h>
+
+
+#include <ctime>
+
+#ifdef HAVE_CUDA
+#include <core/tnlCuda.h>
+#endif
+
+
+template< int Dimension,
+		  typename SchemeHost,
+		  typename SchemeDevice,
+		  typename Device,
+		  typename RealType = double,
+          typename IndexType = int >
+class tnlParallelEikonalSolver
+{};
+
+template<typename SchemeHost, typename SchemeDevice, typename Device>
+class tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >
+{
+public:
+
+	typedef SchemeDevice SchemeTypeDevice;
+	typedef SchemeHost SchemeTypeHost;
+	typedef Device DeviceType;
+	typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorType;
+	typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorType;
+	typedef tnlGrid< 2, double, TNL::Devices::Host, int > MeshType;
+#ifdef HAVE_CUDA
+	typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorTypeCUDA;
+	typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorTypeCUDA;
+	typedef tnlGrid< 2, double, TNL::Devices::Host, int > MeshTypeCUDA;
+#endif
+	tnlParallelEikonalSolver();
+	bool init( const Config::ParameterContainer& parameters );
+	void run();
+
+	void test();
+
+/*private:*/
+
+
+	void synchronize();
+
+	int getOwner( int i) const;
+
+	int getSubgridValue( int i ) const;
+
+	void setSubgridValue( int i, int value );
+
+	int getBoundaryCondition( int i ) const;
+
+	void setBoundaryCondition( int i, int value );
+
+	void stretchGrid();
+
+	void contractGrid();
+
+	VectorType getSubgrid( const int i ) const;
+
+	void insertSubgrid( VectorType u, const int i );
+
+	VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID);
+
+
+	tnlMeshFunction<MeshType> u0;
+	VectorType work_u;
+	IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount;
+	MeshType mesh, subMesh;
+
+//	tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity;
+
+	SchemeHost schemeHost;
+	SchemeDevice schemeDevice;
+	double delta, tau0, stopTime,cflCondition;
+	int gridRows, gridCols, gridLevels, currentStep, n;
+
+	std::clock_t start;
+	double time_diff;
+
+
+	tnlDeviceEnum device;
+
+	tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* getSelf()
+	{
+		return this;
+	};
+
+#ifdef HAVE_CUDA
+
+	tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver;
+
+	double* work_u_cuda;
+
+	int* subgridValues_cuda;
+	int*boundaryConditions_cuda;
+	int* unusedCell_cuda;
+	int* calculationsCount_cuda;
+	double* tmpw;
+	//MeshTypeCUDA mesh_cuda, subMesh_cuda;
+	//SchemeDevice scheme_cuda;
+	//double delta_cuda, tau0_cuda, stopTime_cuda,cflCondition_cuda;
+	//int gridRows_cuda, gridCols_cuda, currentStep_cuda, n_cuda;
+
+	int* runcuda;
+	int run_host;
+
+
+	__device__ void getSubgridCUDA2D( const int i, tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void updateSubgridCUDA2D( const int i, tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void insertSubgridCUDA2D( double u, const int i );
+
+	__device__ void runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID);
+
+	/*__global__ void runCUDA();*/
+
+	//__device__ void synchronizeCUDA();
+
+	__device__ int getOwnerCUDA2D( int i) const;
+
+	__device__ int getSubgridValueCUDA2D( int i ) const;
+
+	__device__ void setSubgridValueCUDA2D( int i, int value );
+
+	__device__ int getBoundaryConditionCUDA2D( int i ) const;
+
+	__device__ void setBoundaryConditionCUDA2D( int i, int value );
+
+	//__device__ bool initCUDA( tnlParallelEikonalSolver<SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+	/*__global__ void initRunCUDA(tnlParallelEikonalSolver<Scheme, double, TNL::Devices::Host, int >* caller);*/
+
+#endif
+
+};
+
+
+
+
+
+
+
+	template<typename SchemeHost, typename SchemeDevice, typename Device>
+	class tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >
+	{
+	public:
+
+		typedef SchemeDevice SchemeTypeDevice;
+		typedef SchemeHost SchemeTypeHost;
+		typedef Device DeviceType;
+		typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorType;
+		typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorType;
+		typedef tnlGrid< 3, double, TNL::Devices::Host, int > MeshType;
+	#ifdef HAVE_CUDA
+		typedef TNL::Containers::Vector< double, TNL::Devices::Host, int > VectorTypeCUDA;
+		typedef TNL::Containers::Vector< int, TNL::Devices::Host, int > IntVectorTypeCUDA;
+		typedef tnlGrid< 3, double, TNL::Devices::Host, int > MeshTypeCUDA;
+	#endif
+		tnlParallelEikonalSolver();
+		bool init( const Config::ParameterContainer& parameters );
+		void run();
+
+		void test();
+
+	/*private:*/
+
+
+		void synchronize();
+
+		int getOwner( int i) const;
+
+		int getSubgridValue( int i ) const;
+
+		void setSubgridValue( int i, int value );
+
+		int getBoundaryCondition( int i ) const;
+
+		void setBoundaryCondition( int i, int value );
+
+		void stretchGrid();
+
+		void contractGrid();
+
+		VectorType getSubgrid( const int i ) const;
+
+		void insertSubgrid( VectorType u, const int i );
+
+		VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID);
+
+
+		tnlMeshFunction<MeshType> u0;
+		VectorType work_u;
+		IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount;
+		MeshType mesh, subMesh;
+		SchemeHost schemeHost;
+		SchemeDevice schemeDevice;
+		double delta, tau0, stopTime,cflCondition;
+		int gridRows, gridCols, gridLevels, currentStep, n;
+
+		std::clock_t start;
+		double time_diff;
+
+
+		tnlDeviceEnum device;
+
+		tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* getSelf()
+		{
+			return this;
+		};
+
+#ifdef HAVE_CUDA
+
+	tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver;
+
+	double* work_u_cuda;
+
+	int* subgridValues_cuda;
+	int*boundaryConditions_cuda;
+	int* unusedCell_cuda;
+	int* calculationsCount_cuda;
+	double* tmpw;
+	//MeshTypeCUDA mesh_cuda, subMesh_cuda;
+	//SchemeDevice scheme_cuda;
+	//double delta_cuda, tau0_cuda, stopTime_cuda,cflCondition_cuda;
+	//int gridRows_cuda, gridCols_cuda, currentStep_cuda, n_cuda;
+
+	int* runcuda;
+	int run_host;
+
+
+	__device__ void getSubgridCUDA3D( const int i, tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void updateSubgridCUDA3D( const int i, tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a);
+
+	__device__ void insertSubgridCUDA3D( double u, const int i );
+
+	__device__ void runSubgridCUDA3D( int boundaryCondition, double* u, int subGridID);
+
+	/*__global__ void runCUDA();*/
+
+	//__device__ void synchronizeCUDA();
+
+	__device__ int getOwnerCUDA3D( int i) const;
+
+	__device__ int getSubgridValueCUDA3D( int i ) const;
+
+	__device__ void setSubgridValueCUDA3D( int i, int value );
+
+	__device__ int getBoundaryConditionCUDA3D( int i ) const;
+
+	__device__ void setBoundaryConditionCUDA3D( int i, int value );
+
+	//__device__ bool initCUDA( tnlParallelEikonalSolver<SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+	/*__global__ void initRunCUDA(tnlParallelEikonalSolver<Scheme, double, TNL::Devices::Host, int >* caller);*/
+
+#endif
+
+};
+
+
+
+
+
+
+#ifdef HAVE_CUDA
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void runCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initRunCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initCUDA2D( tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronizeCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronize2CUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+
+
+
+
+
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void runCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initRunCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void initCUDA3D( tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronizeCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__ void synchronize2CUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
+#endif
+
+
+#ifdef HAVE_CUDA
+__cuda_callable__
+double fabsMin( double x, double y)
+{
+	double fx = fabs(x);
+
+	if(Min(fx,fabs(y)) == fx)
+		return x;
+	else
+		return y;
+}
+
+__cuda_callable__
+double atomicFabsMin(double* address, double val)
+{
+	unsigned long long int* address_as_ull =
+						  (unsigned long long int*)address;
+	unsigned long long int old = *address_as_ull, assumed;
+	do {
+		assumed = old;
+			old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) ));
+	} while (assumed != old);
+	return __longlong_as_double(old);
+}
+
+#endif
+
+#include "tnlParallelEikonalSolver2D_impl.h"
+#include "tnlParallelEikonalSolver3D_impl.h"
+#endif /* TNLPARALLELEIKONALSOLVER_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..8370b069d5c96bfd7921390e46e4979131f15b36
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h
@@ -0,0 +1,1928 @@
+/***************************************************************************
+                          tnlParallelEikonalSolver2D_impl.h  -  description
+                             -------------------
+    begin                : Nov 28 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLPARALLELEIKONALSOLVER2D_IMPL_H_
+#define TNLPARALLELEIKONALSOLVER2D_IMPL_H_
+
+
+#include "tnlParallelEikonalSolver.h"
+#include <core/mfilename.h>
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelEikonalSolver()
+{
+	cout << "a" << endl;
+	this->device = tnlCudaDevice;  /////////////// tnlCuda Device --- vypocet na GPU, TNL::Devices::HostDevice   ---    vypocet na CPU
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+	run_host = 1;
+	}
+#endif
+
+	cout << "b" << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::test()
+{
+/*
+	for(int i =0; i < this->subgridValues.getSize(); i++ )
+	{
+		insertSubgrid(getSubgrid(i), i);
+	}
+*/
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+
+bool tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters )
+{
+	cout << "Initializating solver..." << endl;
+	const String& meshLocation = parameters.getParameter <String>("mesh");
+	this->mesh.load( meshLocation );
+
+	this->n = parameters.getParameter <int>("subgrid-size");
+	cout << "Setting N to " << this->n << endl;
+
+	this->subMesh.setDimensions( this->n, this->n );
+	this->subMesh.setDomain( Containers::StaticVector<2,double>(0.0, 0.0),
+							 Containers::StaticVector<2,double>(mesh.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n)) );
+
+	this->subMesh.save("submesh.tnl");
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	this->u0.load( initialCondition );
+
+	//cout << this->mesh.getCellCenter(0) << endl;
+
+	this->delta = parameters.getParameter <double>("delta");
+	this->delta *= mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >();
+
+	cout << "Setting delta to " << this->delta << endl;
+
+	this->tau0 = parameters.getParameter <double>("initial-tau");
+	cout << "Setting initial tau to " << this->tau0 << endl;
+	this->stopTime = parameters.getParameter <double>("stop-time");
+
+	this->cflCondition = parameters.getParameter <double>("cfl-condition");
+	this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >());
+	cout << "Setting CFL to " << this->cflCondition << endl;
+
+	stretchGrid();
+	this->stopTime /= (double)(this->gridCols);
+	this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0));
+	cout << "Setting stopping time to " << this->stopTime << endl;
+	//this->stopTime = 1.5*((double)(this->n))*parameters.getParameter <double>("stop-time")*this->mesh.template getSpaceStepsProducts< 1, 0 >();
+	//cout << "Setting stopping time to " << this->stopTime << endl;
+
+	cout << "Initializating scheme..." << endl;
+	if(!this->schemeHost.init(parameters))
+	{
+		cerr << "SchemeHost failed to initialize." << endl;
+		return false;
+	}
+	cout << "Scheme initialized." << endl;
+
+	test();
+
+	VectorType* tmp = new VectorType[subgridValues.getSize()];
+	bool containsCurve = false;
+
+#ifdef HAVE_CUDA
+
+	if(this->device == tnlCudaDevice)
+	{
+	/*cout << "Testing... " << endl;
+	if(this->device == tnlCudaDevice)
+	{
+	if( !initCUDA2D(parameters, gridRows, gridCols) )
+		return false;
+	}*/
+		//cout << "s" << endl;
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >));
+	//cout << "s" << endl;
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice);
+	//cout << "s" << endl;
+	double** tmpdev = NULL;
+	cudaMalloc(&tmpdev, sizeof(double*));
+	//double* tmpw;
+	cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double));
+	cudaMalloc(&(this->runcuda), sizeof(int));
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	int* tmpUC;
+	cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int));
+	cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice);
+
+	initCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	//cout << "s " << endl;
+	//cudaMalloc(&(cudaSolver->work_u_cuda), this->work_u.getSize()*sizeof(double));
+	double* tmpu = NULL;
+
+	cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost);
+	//printf("%p %p \n",tmpu,tmpw);
+	cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	//cout << "s "<< endl;
+
+	}
+#endif
+
+	if(this->device == TNL::Devices::HostDevice)
+	{
+	for(int i = 0; i < this->subgridValues.getSize(); i++)
+	{
+
+		if(! tmp[i].setSize(this->n * this->n))
+			cout << "Could not allocate tmp["<< i <<"] array." << endl;
+			tmp[i] = getSubgrid(i);
+		containsCurve = false;
+
+		for(int j = 0; j < tmp[i].getSize(); j++)
+		{
+			if(tmp[i][0]*tmp[i][j] <= 0.0)
+			{
+				containsCurve = true;
+				j=tmp[i].getSize();
+			}
+
+		}
+		if(containsCurve)
+		{
+			//cout << "Computing initial SDF on subgrid " << i << "." << endl;
+			tmp[i] = runSubgrid(0, tmp[i],i);
+			insertSubgrid(tmp[i], i);
+			setSubgridValue(i, 4);
+			//cout << "Computed initial SDF on subgrid " << i  << "." << endl;
+		}
+		containsCurve = false;
+
+	}
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+//		cout << "pre 1 kernel" << endl;
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		initRunCUDA2D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+//		cout << "post 1 kernel" << endl;
+
+	}
+#endif
+
+
+	this->currentStep = 1;
+	if(this->device == TNL::Devices::HostDevice)
+		synchronize();
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		//double * test = (double*)malloc(this->work_u.getSize()*sizeof(double));
+		//cout << test[0] <<"   " << test[1] <<"   " << test[2] <<"   " << test[3] << endl;
+		//cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->tmpw << "   " <<  test[0] <<"   " << test[1] << "   " <<test[2] << "   " <<test[3] << endl;
+
+		TNL_CHECK_CUDA_DEVICE;
+
+		synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cout << test[0] << "   " <<test[1] <<"   " << test[2] << "   " <<test[3] << endl;
+		//cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//TNL_CHECK_CUDA_DEVICE;
+		//cout << this->tmpw << "   " <<  test[0] << "   " <<test[1] << "   " <<test[2] <<"   " << test[3] << endl;
+		//free(test);
+
+	}
+
+#endif
+	cout << "Solver initialized." << endl;
+
+	return true;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::run()
+{
+	if(this->device == TNL::Devices::HostDevice)
+	{
+
+	bool end = false;
+	while ((this->boundaryConditions.max() > 0 ) || !end)
+	{
+		if(this->boundaryConditions.max() == 0 )
+			end=true;
+		else
+			end=false;
+#ifdef HAVE_OPENMP
+#pragma omp parallel for num_threads(4) schedule(dynamic)
+#endif
+		for(int i = 0; i < this->subgridValues.getSize(); i++)
+		{
+			if(getSubgridValue(i) != INT_MAX)
+			{
+				VectorType tmp;
+				tmp.setSize(this->n * this->n);
+				//cout << "subMesh: " << i << ", BC: " << getBoundaryCondition(i) << endl;
+
+				if(getSubgridValue(i) == currentStep+4)
+				{
+
+				if(getBoundaryCondition(i) & 1)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(1, tmp ,i);
+					insertSubgrid( tmp, i);
+					this->calculationsCount[i]++;
+				}
+				if(getBoundaryCondition(i) & 2)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(1, tmp ,i);
+					insertSubgrid( tmp, 2);
+					this->calculationsCount[i]++;
+				}
+				if(getBoundaryCondition(i) & 4)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(4, tmp ,i);
+					insertSubgrid( tmp, i);
+					this->calculationsCount[i]++;
+				}
+				if(getBoundaryCondition(i) & 8)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(8, tmp ,i);
+					insertSubgrid( tmp, i);
+					this->calculationsCount[i]++;
+				}
+				}
+
+				if( ((getBoundaryCondition(i) & 2) )|| (getBoundaryCondition(i) & 1)//)
+					/*	&&(!(getBoundaryCondition(i) & 5) && !(getBoundaryCondition(i) & 10)) */)
+				{
+					//cout << "3 @ " << getBoundaryCondition(i) << endl;
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(1, tmp ,i);
+					insertSubgrid( tmp, 3);
+				}
+				if( ((getBoundaryCondition(i) & 4) )|| (getBoundaryCondition(i) & 1)//)
+					/*	&&(!(getBoundaryCondition(i) & 3) && !(getBoundaryCondition(i) & 12)) */)
+				{
+					//cout << "5 @ " << getBoundaryCondition(i) << endl;
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(5, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( ((getBoundaryCondition(i) & 2) )|| (getBoundaryCondition(i) & 8)//)
+					/*	&&(!(getBoundaryCondition(i) & 12) && !(getBoundaryCondition(i) & 3))*/ )
+				{
+					//cout << "10 @ " << getBoundaryCondition(i) << endl;
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(10, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if(   ((getBoundaryCondition(i) & 4) )|| (getBoundaryCondition(i) & 8)//)
+					/*&&(!(getBoundaryCondition(i) & 10) && !(getBoundaryCondition(i) & 5)) */)
+				{
+					//cout << "12 @ " << getBoundaryCondition(i) << endl;
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(12, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+
+
+				/*if(getBoundaryCondition(i))
+				{
+					insertSubgrid( runSubgrid(15, getSubgrid(i),i), i);
+				}*/
+
+				setBoundaryCondition(i, 0);
+
+				setSubgridValue(i, getSubgridValue(i)-1);
+
+			}
+		}
+		synchronize();
+	}
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		//cout << "fn" << endl;
+		bool end_cuda = false;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cudaMalloc(&runcuda,sizeof(bool));
+		//cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice);
+		//cout << "fn" << endl;
+		bool* tmpb;
+		//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+		//cudaDeviceSynchronize();
+		//TNL_CHECK_CUDA_DEVICE;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cout << "fn" << endl;
+		int i = 1;
+		time_diff = 0.0;
+		while (run_host || !end_cuda)
+		{
+			cout << "Computing at step "<< i++ << endl;
+			if(run_host != 0 )
+				end_cuda = true;
+			else
+				end_cuda = false;
+			//cout << "a" << endl;
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			start = std::clock();
+			runCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+			//cout << "a" << endl;
+			cudaDeviceSynchronize();
+			time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+			//start = std::clock();
+			synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			//time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+
+			//cout << "a" << endl;
+			//run_host = false;
+			//cout << "in kernel loop" << run_host << endl;
+			//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+			cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost);
+			//cout << "in kernel loop" << run_host << endl;
+		}
+		cout << "Solving time was: " << time_diff << endl;
+		//cout << "b" << endl;
+
+		//double* tmpu;
+		//cudaMemcpy(tmpu, &(cudaSolver->work_u_cuda),sizeof(double*), cudaMemcpyHostToDevice);
+		//cudaMemcpy(this->work_u.getData(), tmpu, this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->work_u.getData()[0] << endl;
+
+		//double * test = (double*)malloc(this->work_u.getSize()*sizeof(double));
+		//cout << test[0] << test[1] << test[2] << test[3] << endl;
+		cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->tmpw << "   " <<  test[0] << test[1] << test[2] << test[3] << endl;
+		//free(test);
+
+		cudaDeviceSynchronize();
+	}
+#endif
+	contractGrid();
+	this->u0.save("u-00001.tnl");
+	cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl;
+	cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl;
+	cout << "Solver finished" << endl;
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+		cudaFree(this->runcuda);
+		cudaFree(this->tmpw);
+		cudaFree(this->cudaSolver);
+	}
+#endif
+
+}
+
+//north - 1, east - 2, west - 4, south - 8
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+	cout << "Synchronizig..." << endl;
+	int tmp1, tmp2;
+	int grid1, grid2;
+
+	if(this->currentStep & 1)
+	{
+		for(int j = 0; j < this->gridRows - 1; j++)
+		{
+			for (int i = 0; i < this->gridCols*this->n; i++)
+			{
+				tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i;
+				tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i;
+				grid1 = getSubgridValue(getOwner(tmp1));
+				grid2 = getSubgridValue(getOwner(tmp2));
+				if(getOwner(tmp1)==getOwner(tmp2))
+					cout << "i, j" << i << "," << j << endl;
+				if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					this->work_u[tmp2] = this->work_u[tmp1];
+					this->unusedCell[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp2), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp2)) & 8) )
+						setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8);
+				}
+				else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					this->work_u[tmp1] = this->work_u[tmp2];
+					this->unusedCell[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp1), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp1)) & 1) )
+						setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1);
+				}
+			}
+		}
+
+	}
+	else
+	{
+		for(int i = 1; i < this->gridCols; i++)
+		{
+			for (int j = 0; j < this->gridRows*this->n; j++)
+			{
+				tmp1 = this->gridCols*this->n*j + i*this->n - 1;
+				tmp2 = this->gridCols*this->n*j + i*this->n ;
+				grid1 = getSubgridValue(getOwner(tmp1));
+				grid2 = getSubgridValue(getOwner(tmp2));
+				if(getOwner(tmp1)==getOwner(tmp2))
+					cout << "i, j" << i << "," << j << endl;
+				if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					this->work_u[tmp2] = this->work_u[tmp1];
+					this->unusedCell[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp2), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp2)) & 4) )
+						setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4);
+				}
+				else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					this->work_u[tmp1] = this->work_u[tmp2];
+					this->unusedCell[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						setSubgridValue(getOwner(tmp1), -INT_MAX);
+					}
+					if(! (getBoundaryCondition(getOwner(tmp1)) & 2) )
+						setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2);
+				}
+			}
+		}
+	}
+
+
+	this->currentStep++;
+	int stepValue = this->currentStep + 4;
+	for (int i = 0; i < this->subgridValues.getSize(); i++)
+	{
+		if( getSubgridValue(i) == -INT_MAX )
+			setSubgridValue(i, stepValue);
+	}
+
+	cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl;
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const
+{
+
+	return (i / (this->gridCols*this->n*this->n))*this->gridCols + (i % (this->gridCols*this->n))/this->n;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const
+{
+	return this->subgridValues[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value)
+{
+	this->subgridValues[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const
+{
+	return this->boundaryConditions[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value)
+{
+	this->boundaryConditions[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid()
+{
+	cout << "Stretching grid..." << endl;
+
+
+	this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) );
+	this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) );
+
+	//this->gridCols = (this->mesh.getDimensions().x()-1) / (this->n-1) ;
+	//this->gridRows = (this->mesh.getDimensions().y()-1) / (this->n-1) ;
+
+	cout << "Setting gridCols to " << this->gridCols << "." << endl;
+	cout << "Setting gridRows to " << this->gridRows << "." << endl;
+
+	this->subgridValues.setSize(this->gridCols*this->gridRows);
+	this->subgridValues.setValue(0);
+	this->boundaryConditions.setSize(this->gridCols*this->gridRows);
+	this->boundaryConditions.setValue(0);
+	this->calculationsCount.setSize(this->gridCols*this->gridRows);
+	this->calculationsCount.setValue(0);
+
+	for(int i = 0; i < this->subgridValues.getSize(); i++ )
+	{
+		this->subgridValues[i] = INT_MAX;
+		this->boundaryConditions[i] = 0;
+	}
+
+	int stretchedSize = this->n*this->n*this->gridCols*this->gridRows;
+
+	if(!this->work_u.setSize(stretchedSize))
+		cerr << "Could not allocate memory for stretched grid." << endl;
+	if(!this->unusedCell.setSize(stretchedSize))
+		cerr << "Could not allocate memory for supporting stretched grid." << endl;
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+	for(int i = 0; i < stretchedSize; i++)
+	{
+		this->unusedCell[i] = 1;
+		int diff =(this->n*this->gridCols) - idealStretch ;
+		//cout << "diff = " << diff <<endl;
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if(i%(this->n*this->gridCols) - idealStretch  >= 0)
+		{
+			//cout << i%(this->n*this->gridCols) - idealStretch +1 << endl;
+			k+= i%(this->n*this->gridCols) - idealStretch +1 ;
+		}
+
+		if(i/(this->n*this->gridCols) - idealStretch + 1  > 0)
+		{
+			//cout << i/(this->n*this->gridCols) - idealStretch + 1  << endl;
+			k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ;
+		}
+
+		//cout << "i = " << i << " : i-k = " << i-k << endl;
+		/*int j=(i % (this->n*this->gridCols)) - ( (this->mesh.getDimensions().x() - this->n)/(this->n - 1) + this->mesh.getDimensions().x() - 1)
+				+ (this->n*this->gridCols - this->mesh.getDimensions().x())*(i/(this->n*this->n*this->gridCols)) ;
+
+		if(j > 0)
+			k += j;
+
+		int l = i-k - (this->u0.getSize() - 1);
+		int m = (l % this->mesh.getDimensions().x());
+
+		if(l>0)
+			k+= l + ( (l / this->mesh.getDimensions().x()) + 1 )*this->mesh.getDimensions().x() - (l % this->mesh.getDimensions().x());*/
+
+		this->work_u[i] = this->u0[i-k];
+		//cout << (i-k) <<endl;
+	}
+
+
+	cout << "Grid stretched." << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::contractGrid()
+{
+	cout << "Contracting grid..." << endl;
+	int stretchedSize = this->n*this->n*this->gridCols*this->gridRows;
+
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+	for(int i = 0; i < stretchedSize; i++)
+	{
+		int diff =(this->n*this->gridCols) - idealStretch ;
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if((i%(this->n*this->gridCols) - idealStretch  < 0) && (i/(this->n*this->gridCols) - idealStretch + 1  <= 0))
+		{
+			//cout << i <<" : " <<i-k<< endl;
+			this->u0[i-k] = this->work_u[i];
+		}
+
+	}
+
+	cout << "Grid contracted" << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const
+{
+	VectorType u;
+	u.setSize(this->n*this->n);
+
+	for( int j = 0; j < u.getSize(); j++)
+	{
+		u[j] = this->work_u[ (i / this->gridCols) * this->n*this->n*this->gridCols
+		                     + (i % this->gridCols) * this->n
+		                     + (j/this->n) * this->n*this->gridCols
+		                     + (j % this->n) ];
+	}
+	return u;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i )
+{
+
+	for( int j = 0; j < this->n*this->n; j++)
+	{
+		int index = (i / this->gridCols)*this->n*this->n*this->gridCols
+					+ (i % this->gridCols)*this->n
+					+ (j/this->n)*this->n*this->gridCols
+					+ (j % this->n);
+		//OMP LOCK index
+		if( (fabs(this->work_u[index]) > fabs(u[j])) || (this->unusedCell[index] == 1) )
+		{
+			this->work_u[index] = u[j];
+			this->unusedCell[index] = 0;
+		}
+		//OMP UNLOCK index
+	}
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID)
+{
+
+	VectorType fu;
+
+	fu.setLike(u);
+	fu.setValue( 0.0 );
+
+/*
+ *          Insert Euler-Solver Here
+ */
+
+	/**/
+
+	/*for(int i = 0; i < u.getSize(); i++)
+	{
+		int x = this->subMesh.getCellCoordinates(i).x();
+		int y = this->subMesh.getCellCoordinates(i).y();
+
+		if(x == 0 && (boundaryCondition & 4) && y ==0)
+		{
+			if((u[subMesh.getCellYSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0)
+			{
+				//cout << "x = 0; y = 0" << endl;
+				u[i] = u[subMesh.getCellYSuccessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >();
+			}
+		}
+		else if(x == 0 && (boundaryCondition & 4) && y == subMesh.getDimensions().y() - 1)
+		{
+			if((u[subMesh.getCellYPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0)
+			{
+				//cout << "x = 0; y = n" << endl;
+				u[i] = u[subMesh.getCellYPredecessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >();
+			}
+		}
+
+
+		else if(x == subMesh.getDimensions().x() - 1 && (boundaryCondition & 2) && y ==0)
+		{
+			if((u[subMesh.getCellYSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0)
+			{
+				//cout << "x = n; y = 0" << endl;
+				u[i] = u[subMesh.getCellYSuccessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >();
+			}
+		}
+		else if(x == subMesh.getDimensions().x() - 1 && (boundaryCondition & 2) && y == subMesh.getDimensions().y() - 1)
+		{
+			if((u[subMesh.getCellYPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0)
+			{
+				//cout << "x = n; y = n" << endl;
+				u[i] = u[subMesh.getCellYPredecessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >();
+			}
+		}
+
+
+		else if(y == 0 && (boundaryCondition & 8) && x ==0)
+		{
+			if((u[subMesh.getCellXSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0)
+			{
+				//cout << "y = 0; x = 0" << endl;
+				u[i] = u[subMesh.getCellXSuccessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >();
+			}
+		}
+		else if(y == 0 && (boundaryCondition & 8) && x == subMesh.getDimensions().x() - 1)
+		{
+			if((u[subMesh.getCellXPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0)
+			{
+				//cout << "y = 0; x = n" << endl;
+				u[i] = u[subMesh.getCellXPredecessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >();
+			}
+		}
+
+
+		else if(y == subMesh.getDimensions().y() - 1 && (boundaryCondition & 1) && x ==0)
+		{
+			if((u[subMesh.getCellXSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0)			{
+				//cout << "y = n; x = 0" << endl;
+				u[i] = u[subMesh.getCellXSuccessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >();
+			}
+		}
+		else if(y == subMesh.getDimensions().y() - 1 && (boundaryCondition & 1) && x == subMesh.getDimensions().x() - 1)
+		{
+			if((u[subMesh.getCellXPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0)
+			{
+				//cout << "y = n; x = n" << endl;
+				u[i] = u[subMesh.getCellXPredecessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >();
+			}
+		}
+	}*/
+
+	/**/
+
+
+/*	bool tmp = false;
+	for(int i = 0; i < u.getSize(); i++)
+	{
+		if(u[0]*u[i] <= 0.0)
+			tmp=true;
+	}
+
+
+	if(tmp)
+	{}
+	else if(boundaryCondition == 4)
+	{
+		int i;
+		for(i = 0; i < u.getSize() - subMesh.getDimensions().x() ; i=subMesh.getCellYSuccessor(i))
+		{
+			int j;
+			for(j = i; j < subMesh.getDimensions().x() - 1; j=subMesh.getCellXSuccessor(j))
+			{
+				u[j] = u[i];
+			}
+			u[j] = u[i];
+		}
+		int j;
+		for(j = i; j < subMesh.getDimensions().x() - 1; j=subMesh.getCellXSuccessor(j))
+		{
+			u[j] = u[i];
+		}
+		u[j] = u[i];
+	}
+	else if(boundaryCondition == 8)
+	{
+		int i;
+		for(i = 0; i < subMesh.getDimensions().x() - 1; i=subMesh.getCellXSuccessor(i))
+		{
+			int j;
+			for(j = i; j < u.getSize() - subMesh.getDimensions().x(); j=subMesh.getCellYSuccessor(j))
+			{
+				u[j] = u[i];
+			}
+			u[j] = u[i];
+		}
+		int j;
+		for(j = i; j < u.getSize() - subMesh.getDimensions().x(); j=subMesh.getCellYSuccessor(j))
+		{
+			u[j] = u[i];
+		}
+		u[j] = u[i];
+
+	}
+	else if(boundaryCondition == 2)
+	{
+		int i;
+		for(i = subMesh.getDimensions().x() - 1; i < u.getSize() - subMesh.getDimensions().x() ; i=subMesh.getCellYSuccessor(i))
+		{
+			int j;
+			for(j = i; j > (i-1)*subMesh.getDimensions().x(); j=subMesh.getCellXPredecessor(j))
+			{
+				u[j] = u[i];
+			}
+			u[j] = u[i];
+		}
+		int j;
+		for(j = i; j > (i-1)*subMesh.getDimensions().x(); j=subMesh.getCellXPredecessor(j))
+		{
+			u[j] = u[i];
+		}
+		u[j] = u[i];
+	}
+	else if(boundaryCondition == 1)
+	{
+		int i;
+		for(i = (subMesh.getDimensions().y() - 1)*subMesh.getDimensions().x(); i < u.getSize() - 1; i=subMesh.getCellXSuccessor(i))
+		{
+			int j;
+			for(j = i; j >=subMesh.getDimensions().x(); j=subMesh.getCellYPredecessor(j))
+			{
+				u[j] = u[i];
+			}
+			u[j] = u[i];
+		}
+		int j;
+		for(j = i; j >=subMesh.getDimensions().x(); j=subMesh.getCellYPredecessor(j))
+		{
+			u[j] = u[i];
+		}
+		u[j] = u[i];
+	}
+*/
+	/**/
+
+
+
+	bool tmp = false;
+	for(int i = 0; i < u.getSize(); i++)
+	{
+		if(u[0]*u[i] <= 0.0)
+			tmp=true;
+		int centerGID = (this->n*(subGridID / this->gridRows)+ (this->n >> 1))*(this->n*this->gridCols) + this->n*(subGridID % this->gridRows) + (this->n >> 1);
+		if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0)
+			tmp = true;
+	}
+	//if(this->currentStep + 3 < getSubgridValue(subGridID))
+		//tmp = true;
+
+
+	double value = sign(u[0]) * u.absMax();
+
+	if(tmp)
+	{}
+
+
+	//north - 1, east - 2, west - 4, south - 8
+	else if(boundaryCondition == 4)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j = 1;j < this->n; j++)
+				//if(fabs(u[i*this->n + j]) <  fabs(u[i*this->n]))
+				u[i*this->n + j] = value;// u[i*this->n];
+	}
+	else if(boundaryCondition == 2)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j =0 ;j < this->n -1; j++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1]))
+				u[i*this->n + j] = value;// u[(i+1)*this->n - 1];
+	}
+	else if(boundaryCondition == 1)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 0;i < this->n - 1; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)]))
+				u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)];
+	}
+	else if(boundaryCondition == 8)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 1;i < this->n; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j]))
+				u[i*this->n + j] = value;// u[j];
+	}
+
+/*
+
+	else if(boundaryCondition == 5)
+	{
+		for(int i = 0; i < this->n - 1; i++)
+			for(int j = 1;j < this->n; j++)
+				//if(fabs(u[i*this->n + j]) <  fabs(u[i*this->n]))
+				u[i*this->n + j] = value;// u[i*this->n];
+	}
+	else if(boundaryCondition == 10)
+	{
+		for(int i = 1; i < this->n; i++)
+			for(int j =0 ;j < this->n -1; j++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1]))
+				u[i*this->n + j] = value;// u[(i+1)*this->n - 1];
+	}
+	else if(boundaryCondition == 3)
+	{
+		for(int j = 0; j < this->n - 1; j++)
+			for(int i = 0;i < this->n - 1; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)]))
+				u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)];
+	}
+	else if(boundaryCondition == 12)
+	{
+		for(int j = 1; j < this->n; j++)
+			for(int i = 1;i < this->n; i++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j]))
+				u[i*this->n + j] = value;// u[j];
+	}
+*/
+
+
+	/**/
+
+	/*if (u.max() > 0.0)
+		this->stopTime *=(double) this->gridCols;*/
+
+
+   double time = 0.0;
+   double currentTau = this->tau0;
+   double finalTime = this->stopTime;// + 3.0*(u.max() - u.min());
+   if( time + currentTau > finalTime ) currentTau = finalTime - time;
+
+   double maxResidue( 1.0 );
+   //double lastResidue( 10000.0 );
+   tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+   while( time < finalTime /*|| maxResidue > subMesh.template getSpaceStepsProducts< 1, 0 >()*/)
+   {
+      /****
+       * Compute the RHS
+       */
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+			Entity.setCoordinates(Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()));
+			Entity.refresh();
+			neighborEntities.refresh(subMesh,Entity.getIndex());
+    	  fu[ i ] = schemeHost.getValue( this->subMesh, i, Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()), u, time, boundaryCondition,neighborEntities);
+      }
+      maxResidue = fu. absMax();
+
+
+      if( this -> cflCondition * maxResidue != 0.0)
+    	  currentTau =  this -> cflCondition / maxResidue;
+
+     /* if (maxResidue < 0.05)
+    	  cout << "Max < 0.05" << endl;*/
+      if(currentTau > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >())
+      {
+    	  //cout << currentTau << " >= " << 2.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >() << endl;
+    	  currentTau = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >();
+      }
+      /*if(maxResidue > lastResidue)
+    	  currentTau *=(1.0/10.0);*/
+
+
+      if( time + currentTau > finalTime ) currentTau = finalTime - time;
+//      for( int i = 0; i < fu.getSize(); i ++ )
+//      {
+//    	  //cout << "Too big RHS! i = " << i << ", fu = " << fu[i] << ", u = " << u[i] << endl;
+//    	  if((u[i]+currentTau * fu[ i ])*u[i] < 0.0 && fu[i] != 0.0 && u[i] != 0.0 )
+//    		  currentTau = fabs(u[i]/(2.0*fu[i]));
+//
+//      }
+
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+    	  double add = u[i] + currentTau * fu[ i ];
+    	  //if( fabs(u[i]) < fabs(add) or (this->subgridValues[subGridID] == this->currentStep +4) )
+    		  u[ i ] = add;
+      }
+      time += currentTau;
+
+      //cout << '\r' << flush;
+     //cout << maxResidue << "   " << currentTau << " @ " << time << flush;
+     //lastResidue = maxResidue;
+   }
+   //cout << "Time: " << time << ", Res: " << maxResidue <<endl;
+	/*if (u.max() > 0.0)
+		this->stopTime /=(double) this->gridCols;*/
+
+	VectorType solution;
+	solution.setLike(u);
+    for( int i = 0; i < u.getSize(); i ++ )
+  	{
+    	solution[i]=u[i];
+   	}
+	return solution;
+}
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA2D( const int i ,tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+	//int j = threadIdx.x + threadIdx.y * blockDim.x;
+	int th = (blockIdx.y) * caller->n*caller->n*caller->gridCols
+            + (blockIdx.x) * caller->n
+            + threadIdx.y * caller->n*caller->gridCols
+            + threadIdx.x;
+	//printf("i= %d,j= %d,th= %d\n",i,j,th);
+	*a = caller->work_u_cuda[th];
+	//printf("Hi %f \n", *a);
+	//return ret;
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA2D( const int i ,tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+//	int j = threadIdx.x + threadIdx.y * blockDim.x;
+	int index = (blockIdx.y) * caller->n*caller->n*caller->gridCols
+            + (blockIdx.x) * caller->n
+            + threadIdx.y * caller->n*caller->gridCols
+            + threadIdx.x;
+
+	if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) )
+	{
+		caller->work_u_cuda[index] = *a;
+		caller->unusedCell_cuda[index] = 0;
+
+	}
+
+	*a = caller->work_u_cuda[index];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA2D( double u, const int i )
+{
+
+
+//	int j = threadIdx.x + threadIdx.y * blockDim.x;
+	//printf("j = %d, u = %f\n", j,u);
+
+		int index = (blockIdx.y)*this->n*this->n*this->gridCols
+					+ (blockIdx.x)*this->n
+					+ threadIdx.y*this->n*this->gridCols
+					+ threadIdx.x;
+
+		//printf("i= %d,j= %d,index= %d\n",i,j,index);
+		if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) )
+		{
+			this->work_u_cuda[index] = u;
+			this->unusedCell_cuda[index] = 0;
+
+		}
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID)
+{
+
+	__shared__ int tmp;
+	__shared__ double value;
+	//double tmpRes = 0.0;
+	volatile double* sharedTau = &u[blockDim.x*blockDim.y];
+	volatile double* absVal = &u[2*blockDim.x*blockDim.y];
+	int i = threadIdx.x;
+	int j = threadIdx.y;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+	bool computeFU = !((i == 0 && (boundaryCondition & 4)) or
+			 (i == blockDim.x - 1 && (boundaryCondition & 2)) or
+			 (j == 0 && (boundaryCondition & 8)) or
+			 (j == blockDim.y - 1  && (boundaryCondition & 1)));
+
+	if(l == 0)
+	{
+		tmp = 0;
+		int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1))*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1);
+		if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0)
+			tmp = 1;
+	}
+	__syncthreads();
+
+	/*if(!tmp && (u[0]*u[l] <= 0.0))
+		atomicMax( &tmp, 1);*/
+
+	__syncthreads();
+	if(tmp !=1)
+	{
+//		if(computeFU)
+//			absVal[l]=0.0;
+//		else
+//			absVal[l] = fabs(u[l]);
+//
+//		__syncthreads();
+//
+//	      if((blockDim.x == 16) && (l < 128))		absVal[l] = Max(absVal[l],absVal[l+128]);
+//	      __syncthreads();
+//	      if((blockDim.x == 16) && (l < 64))		absVal[l] = Max(absVal[l],absVal[l+64]);
+//	      __syncthreads();
+//	      if(l < 32)    							absVal[l] = Max(absVal[l],absVal[l+32]);
+//	      if(l < 16)								absVal[l] = Max(absVal[l],absVal[l+16]);
+//	      if(l < 8)									absVal[l] = Max(absVal[l],absVal[l+8]);
+//	      if(l < 4)									absVal[l] = Max(absVal[l],absVal[l+4]);
+//	      if(l < 2)									absVal[l] = Max(absVal[l],absVal[l+2]);
+//	      if(l < 1)									value   = sign(u[0])*Max(absVal[l],absVal[l+1]);
+//		__syncthreads();
+//
+//		if(computeFU)
+//			u[l] = value;
+		if(computeFU)
+		{
+			if(boundaryCondition == 4)
+				u[l] = u[threadIdx.y * blockDim.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x) ;//+  2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x+this->n);
+			else if(boundaryCondition == 2)
+				u[l] = u[threadIdx.y * blockDim.x + blockDim.x - 1] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.x);//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(blockDim.x - threadIdx.x - 1+this->n);
+			else if(boundaryCondition == 8)
+				u[l] = u[threadIdx.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y+this->n);
+			else if(boundaryCondition == 1)
+				u[l] = u[(blockDim.y - 1)* blockDim.x + threadIdx.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.y) ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(blockDim.y - threadIdx.y  - 1 +this->n);
+		}
+	}
+
+   double time = 0.0;
+   __shared__ double currentTau;
+   double cfl = this->cflCondition;
+   double fu = 0.0;
+//   if(threadIdx.x * threadIdx.y == 0)
+//   {
+//	   currentTau = finalTime;
+//   }
+   double finalTime = this->stopTime;
+   __syncthreads();
+//   if( time + currentTau > finalTime ) currentTau = finalTime - time;
+
+   tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighborEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<2,int>(i,j));
+   Entity.refresh();
+   neighborEntities.refresh(subMesh,Entity.getIndex());
+
+
+   while( time < finalTime )
+   {
+	  if(computeFU)
+		  fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<2,int>(i,j)/*this->subMesh.getCellCoordinates(l)*/, u, time, boundaryCondition, neighborEntities);
+
+	  sharedTau[l]=abs(cfl/fu);
+
+      if(l == 0)
+      {
+    	  if(sharedTau[0] > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >())	sharedTau[0] = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >();
+      }
+      else if(l == blockDim.x*blockDim.y - 1)
+    	  if( time + sharedTau[l] > finalTime )		sharedTau[l] = finalTime - time;
+
+
+//      if(  (sign(u[l]+sharedTau[l]*fu) != sign(u[l])) && fu != 0.0 && fu != -0.0)
+//    	  {
+//    	  printf("orig: %10f", sharedTau[l]);
+//    	  sharedTau[l]=abs(u[l]/(1.1*fu)) ;
+//    	  printf("   new: %10f\n", sharedTau[l]);
+//    	  }
+
+
+
+      if((blockDim.x == 16) && (l < 128))		sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]);
+      __syncthreads();
+      if((blockDim.x == 16) && (l < 64))		sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]);
+      __syncthreads();
+      if(l < 32)    							sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]);
+      if(l < 16)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]);
+      if(l < 8)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]);
+      if(l < 4)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]);
+      if(l < 2)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]);
+      if(l < 1)									currentTau   = Min(sharedTau[l],sharedTau[l+1]);
+	__syncthreads();
+
+      u[l] += currentTau * fu;
+      time += currentTau;
+   }
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA2D(int i) const
+{
+
+	return ((i / (this->gridCols*this->n*this->n))*this->gridCols
+			+ (i % (this->gridCols*this->n))/this->n);
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA2D( int i ) const
+{
+	return this->subgridValues_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA2D(int i, int value)
+{
+	this->subgridValues_cuda[i] = value;
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA2D( int i ) const
+{
+	return this->boundaryConditions_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA2D(int i, int value)
+{
+	this->boundaryConditions_cuda[i] = value;
+}
+
+
+
+//north - 1, east - 2, west - 4, south - 8
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/synchronizeCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+
+	__shared__ int boundary[4]; // north,east,west,south
+	__shared__ int subgridValue;
+	__shared__ int newSubgridValue;
+
+
+	int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x;
+	double u = cudaSolver->work_u_cuda[gid];
+	double u_cmp;
+	int subgridValue_cmp=INT_MAX;
+	int boundary_index=0;
+
+
+	if(threadIdx.x+threadIdx.y == 0)
+	{
+		subgridValue = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x);
+		boundary[0] = 0;
+		boundary[1] = 0;
+		boundary[2] = 0;
+		boundary[3] = 0;
+		newSubgridValue = 0;
+		//printf("%d   %d\n", blockDim.x, gridDim.x);
+	}
+	__syncthreads();
+
+
+
+	if(		(threadIdx.x == 0 				/*				&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == 0 				 	/*			&& (cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.x == blockDim.x - 1 	 /*	&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == blockDim.y - 1 	 /*	&& (cudaSolver->currentStep & 1)*/) 		)
+	{
+		if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x - 1);
+			boundary_index = 2;
+		}
+
+		if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x + 1);
+			boundary_index = 1;
+		}
+
+		__threadfence();
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+			u=u_cmp;
+		}
+		__threadfence();
+		if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y - 1)*gridDim.x + blockIdx.x);
+			boundary_index = 3;
+		}
+		if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y + 1)*gridDim.x + blockIdx.x);
+			boundary_index = 0;
+		}
+
+//		__threadfence();
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+		}
+	}
+	__threadfence();
+	__syncthreads();
+
+	if(threadIdx.x+threadIdx.y == 0)
+	{
+		if(subgridValue == INT_MAX && newSubgridValue !=0)
+			cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, -INT_MAX);
+
+		cudaSolver->setBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, 	boundary[0] +
+																				2 * boundary[1] +
+																				4 * boundary[2] +
+																				8 * boundary[3]);
+
+
+		if(blockIdx.x+blockIdx.y ==0)
+		{
+			cudaSolver->currentStep = cudaSolver->currentStep + 1;
+			*(cudaSolver->runcuda) = 0;
+		}
+//
+//		int stepValue = cudaSolver->currentStep + 4;
+//		if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX )
+//				cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue);
+//
+//		atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x));
+	}
+
+
+	/*
+	//printf("I am not an empty kernel!\n");
+	//cout << "Synchronizig..." << endl;
+	int tmp1, tmp2;
+	int grid1, grid2;
+
+	if(cudaSolver->currentStep & 1)
+	{
+		//printf("I am not an empty kernel! 1\n");
+		for(int j = 0; j < cudaSolver->gridRows - 1; j++)
+		{
+			//printf("I am not an empty kernel! 3\n");
+			for (int i = 0; i < cudaSolver->gridCols*cudaSolver->n; i++)
+			{
+				tmp1 = cudaSolver->gridCols*cudaSolver->n*((cudaSolver->n-1)+j*cudaSolver->n) + i;
+				tmp2 = cudaSolver->gridCols*cudaSolver->n*((cudaSolver->n)+j*cudaSolver->n) + i;
+				grid1 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1));
+				grid2 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2));
+
+				if ((fabs(cudaSolver->work_u_cuda[tmp1]) < fabs(cudaSolver->work_u_cuda[tmp2]) - cudaSolver->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					//printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2));
+					cudaSolver->work_u_cuda[tmp2] = cudaSolver->work_u_cuda[tmp1];
+					cudaSolver->unusedCell_cuda[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), -INT_MAX);
+					}
+					if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)) & 8) )
+						cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2))+8);
+				}
+				else if ((fabs(cudaSolver->work_u_cuda[tmp1]) > fabs(cudaSolver->work_u_cuda[tmp2]) + cudaSolver->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					//printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2));
+					cudaSolver->work_u_cuda[tmp1] = cudaSolver->work_u_cuda[tmp2];
+					cudaSolver->unusedCell_cuda[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), -INT_MAX);
+					}
+					if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)) & 1) )
+						cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1))+1);
+				}
+			}
+		}
+
+	}
+	else
+	{
+		//printf("I am not an empty kernel! 2\n");
+		for(int i = 1; i < cudaSolver->gridCols; i++)
+		{
+			//printf("I am not an empty kernel! 4\n");
+			for (int j = 0; j < cudaSolver->gridRows*cudaSolver->n; j++)
+			{
+
+				tmp1 = cudaSolver->gridCols*cudaSolver->n*j + i*cudaSolver->n - 1;
+				tmp2 = cudaSolver->gridCols*cudaSolver->n*j + i*cudaSolver->n ;
+				grid1 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1));
+				grid2 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2));
+
+				if ((fabs(cudaSolver->work_u_cuda[tmp1]) < fabs(cudaSolver->work_u_cuda[tmp2]) - cudaSolver->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+				{
+					//printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2));
+					cudaSolver->work_u_cuda[tmp2] = cudaSolver->work_u_cuda[tmp1];
+					cudaSolver->unusedCell_cuda[tmp2] = 0;
+					if(grid2 == INT_MAX)
+					{
+						cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), -INT_MAX);
+					}
+					if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)) & 4) )
+						cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2))+4);
+				}
+				else if ((fabs(cudaSolver->work_u_cuda[tmp1]) > fabs(cudaSolver->work_u_cuda[tmp2]) + cudaSolver->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+				{
+					//printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2));
+					cudaSolver->work_u_cuda[tmp1] = cudaSolver->work_u_cuda[tmp2];
+					cudaSolver->unusedCell_cuda[tmp1] = 0;
+					if(grid1 == INT_MAX)
+					{
+						cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), -INT_MAX);
+					}
+					if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)) & 2) )
+						cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1))+2);
+				}
+			}
+		}
+	}
+	//printf("I am not an empty kernel! 5 cudaSolver->currentStep : %d \n", cudaSolver->currentStep);
+
+	cudaSolver->currentStep = cudaSolver->currentStep + 1;
+	int stepValue = cudaSolver->currentStep + 4;
+	for (int i = 0; i < cudaSolver->gridRows * cudaSolver->gridCols; i++)
+	{
+		if( cudaSolver->getSubgridValueCUDA2D(i) == -INT_MAX )
+			cudaSolver->setSubgridValueCUDA2D(i, stepValue);
+	}
+
+	int maxi = 0;
+	for(int q=0; q < cudaSolver->gridRows*cudaSolver->gridCols;q++)
+	{
+		//printf("%d : %d\n", q, cudaSolver->boundaryConditions_cuda[q]);
+		maxi=Max(maxi,cudaSolver->getBoundaryConditionCUDA2D(q));
+	}
+	//printf("I am not an empty kernel! %d\n", maxi);
+	*(cudaSolver->runcuda) = (maxi > 0);
+	//printf("I am not an empty kernel! 7 %d\n", cudaSolver->boundaryConditions_cuda[0]);
+	//cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl;
+*/
+}
+
+
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void synchronize2CUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver)
+{
+//	if(blockIdx.x+blockIdx.y ==0)
+//	{
+//		cudaSolver->currentStep = cudaSolver->currentStep + 1;
+//		*(cudaSolver->runcuda) = 0;
+//	}
+
+	int stepValue = cudaSolver->currentStep + 4;
+	if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX )
+			cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue);
+
+	atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x));
+}
+
+
+
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/initCUDA2D( tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3)
+{
+	//cout << "Initializating solver..." << endl;
+	//const String& meshLocation = parameters.getParameter <String>("mesh");
+	//this->mesh_cuda.load( meshLocation );
+
+	//this->n_cuda = parameters.getParameter <int>("subgrid-size");
+	//cout << "Setting N << this->n_cuda << endl;
+
+	//this->subMesh_cuda.setDimensions( this->n_cuda, this->n_cuda );
+	//this->subMesh_cuda.setDomain( Containers::StaticVector<2,double>(0.0, 0.0),
+							 //Containers::StaticVector<2,double>(this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n_cuda), this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n_cuda)) );
+
+	//this->subMesh_cuda.save("submesh.tnl");
+
+//	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+//	this->u0.load( initialCondition );
+
+	//cout << this->mesh.getCellCenter(0) << endl;
+
+	//this->delta_cuda = parameters.getParameter <double>("delta");
+	//this->delta_cuda *= this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >();
+
+	//cout << "Setting delta to " << this->delta << endl;
+
+	//this->tau0_cuda = parameters.getParameter <double>("initial-tau");
+	//cout << "Setting initial tau to " << this->tau0_cuda << endl;
+	//this->stopTime_cuda = parameters.getParameter <double>("stop-time");
+
+	//this->cflCondition_cuda = parameters.getParameter <double>("cfl-condition");
+	//this -> cflCondition_cuda *= sqrt(this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >());
+	//cout << "Setting CFL to " << this->cflCondition << endl;
+////
+////
+
+//	this->gridRows_cuda = gridRows;
+//	this->gridCols_cuda = gridCols;
+
+	cudaSolver->work_u_cuda = ptr;//(double*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(double));
+	cudaSolver->unusedCell_cuda = ptr3;//(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(int));
+	cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int));
+	cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int));
+	cudaSolver->runcuda = ptr2;//(bool*)malloc(sizeof(bool));
+	*(cudaSolver->runcuda) = 1;
+	cudaSolver->currentStep = 1;
+	//cudaMemcpy(ptr,&(cudaSolver->work_u_cuda), sizeof(double*),cudaMemcpyDeviceToHost);
+	//ptr = cudaSolver->work_u_cuda;
+	printf("GPU memory allocated.\n");
+
+	for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows; i++)
+	{
+		cudaSolver->subgridValues_cuda[i] = INT_MAX;
+		cudaSolver->boundaryConditions_cuda[i] = 0;
+	}
+
+	/*for(long int j = 0; j < cudaSolver->n*cudaSolver->n*cudaSolver->gridCols*cudaSolver->gridRows; j++)
+	{
+		printf("%d\n",j);
+		cudaSolver->unusedCell_cuda[ j] = 1;
+	}*/
+	printf("GPU memory initialized.\n");
+
+
+	//cudaSolver->work_u_cuda[50] = 32.153438;
+////
+////
+	//stretchGrid();
+	//this->stopTime_cuda /= (double)(this->gridCols_cuda);
+	//this->stopTime_cuda *= (1.0+1.0/((double)(this->n_cuda) - 1.0));
+	//cout << "Setting stopping time to " << this->stopTime << endl;
+	//this->stopTime_cuda = 1.5*((double)(this->n_cuda))*parameters.getParameter <double>("stop-time")*this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >();
+	//cout << "Setting stopping time to " << this->stopTime << endl;
+
+	//cout << "Initializating scheme..." << endl;
+	//if(!this->schemeDevice.init(parameters))
+//	{
+		//cerr << "Scheme failed to initialize." << endl;
+//		return false;
+//	}
+	//cout << "Scheme initialized." << endl;
+
+	//test();
+
+//	this->currentStep_cuda = 1;
+	//return true;
+}
+
+
+
+
+//extern __shared__ double array[];
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/initRunCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller)
+
+{
+
+
+	extern __shared__ double u[];
+	//printf("%p\n",caller->work_u_cuda);
+
+	int i = blockIdx.y * gridDim.x + blockIdx.x;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+
+	__shared__ int containsCurve;
+	if(l == 0)
+		containsCurve = 0;
+
+	//double a;
+	caller->getSubgridCUDA2D(i,caller, &u[l]);
+	//printf("%f   %f\n",a , u[l]);
+	//u[l] = a;
+	//printf("Hi %f \n", u[l]);
+	__syncthreads();
+	//printf("hurewrwr %f \n", u[l]);
+	if(u[0] * u[l] <= 0.0)
+	{
+		//printf("contains %d \n",i);
+		atomicMax( &containsCurve, 1);
+	}
+
+	__syncthreads();
+	//printf("hu");
+	//printf("%d : %f\n", l, u[l]);
+	if(containsCurve == 1)
+	{
+		//printf("have curve \n");
+		caller->runSubgridCUDA2D(0,u,i);
+		//printf("%d : %f\n", l, u[l]);
+		__syncthreads();
+		caller->insertSubgridCUDA2D(u[l],i);
+		__syncthreads();
+		if(l == 0)
+			caller->setSubgridValueCUDA2D(i, 4);
+	}
+
+
+}
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/runCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller)
+{
+	extern __shared__ double u[];
+	int i = blockIdx.y * gridDim.x + blockIdx.x;
+	int l = threadIdx.y * blockDim.x + threadIdx.x;
+	int bound = caller->getBoundaryConditionCUDA2D(i);
+
+	if(caller->getSubgridValueCUDA2D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA2D(i) > 0)
+	{
+		caller->getSubgridCUDA2D(i,caller, &u[l]);
+
+		//if(l == 0)
+			//printf("i = %d, bound = %d\n",i,caller->getSubgridValueCUDA2D(i));
+		if(caller->getSubgridValueCUDA2D(i) == caller->currentStep+4)
+		{
+			if(bound & 1)
+			{
+				caller->runSubgridCUDA2D(1,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 2 )
+			{
+				caller->runSubgridCUDA2D(2,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 4)
+			{
+				caller->runSubgridCUDA2D(4,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 8)
+			{
+				caller->runSubgridCUDA2D(8,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+
+
+
+
+
+			if( ((bound & 3 )))
+				{
+					caller->runSubgridCUDA2D(3,u,i);
+					//__syncthreads();
+					//caller->insertSubgridCUDA2D(u[l],i);
+					//__syncthreads();
+					//caller->getSubgridCUDA2D(i,caller, &u[l]);
+					caller->updateSubgridCUDA2D(i,caller, &u[l]);
+					__syncthreads();
+				}
+				if( ((bound & 5 )))
+				{
+					caller->runSubgridCUDA2D(5,u,i);
+					//__syncthreads();
+					//caller->insertSubgridCUDA2D(u[l],i);
+					//__syncthreads();
+					//caller->getSubgridCUDA2D(i,caller, &u[l]);
+					caller->updateSubgridCUDA2D(i,caller, &u[l]);
+					__syncthreads();
+				}
+				if( ((bound & 10 )))
+				{
+					caller->runSubgridCUDA2D(10,u,i);
+					//__syncthreads();
+					//caller->insertSubgridCUDA2D(u[l],i);
+					//__syncthreads();
+					//caller->getSubgridCUDA2D(i,caller, &u[l]);
+					caller->updateSubgridCUDA2D(i,caller, &u[l]);
+					__syncthreads();
+				}
+				if(   (bound & 12 ))
+				{
+					caller->runSubgridCUDA2D(12,u,i);
+					//__syncthreads();
+					//caller->insertSubgridCUDA2D(u[l],i);
+					//__syncthreads();
+					//caller->getSubgridCUDA2D(i,caller, &u[l]);
+					caller->updateSubgridCUDA2D(i,caller, &u[l]);
+					__syncthreads();
+				}
+
+
+
+
+
+		}
+
+
+		else
+		{
+
+
+
+
+
+
+
+
+
+			if( ((bound == 2)))
+						{
+							caller->runSubgridCUDA2D(2,u,i);
+							//__syncthreads();
+							//caller->insertSubgridCUDA2D(u[l],i);
+							//__syncthreads();
+							//caller->getSubgridCUDA2D(i,caller, &u[l]);
+							caller->updateSubgridCUDA2D(i,caller, &u[l]);
+							__syncthreads();
+						}
+						if( ((bound == 1) ))
+						{
+							caller->runSubgridCUDA2D(1,u,i);
+							//__syncthreads();
+							//caller->insertSubgridCUDA2D(u[l],i);
+							//__syncthreads();
+							//caller->getSubgridCUDA2D(i,caller, &u[l]);
+							caller->updateSubgridCUDA2D(i,caller, &u[l]);
+							__syncthreads();
+						}
+						if( ((bound == 8) ))
+						{
+							caller->runSubgridCUDA2D(8,u,i);
+							//__syncthreads();
+							//caller->insertSubgridCUDA2D(u[l],i);
+							//__syncthreads();
+							//caller->getSubgridCUDA2D(i,caller, &u[l]);
+							caller->updateSubgridCUDA2D(i,caller, &u[l]);
+							__syncthreads();
+						}
+						if(   (bound == 4))
+						{
+							caller->runSubgridCUDA2D(4,u,i);
+							//__syncthreads();
+							//caller->insertSubgridCUDA2D(u[l],i);
+							//__syncthreads();
+							//caller->getSubgridCUDA2D(i,caller, &u[l]);
+							caller->updateSubgridCUDA2D(i,caller, &u[l]);
+							__syncthreads();
+						}
+
+
+
+
+
+
+
+
+
+
+			if( ((bound & 3) ))
+			{
+				caller->runSubgridCUDA2D(3,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if( ((bound & 5) ))
+			{
+				caller->runSubgridCUDA2D(5,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if( ((bound & 10) ))
+			{
+				caller->runSubgridCUDA2D(10,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(   (bound & 12) )
+			{
+				caller->runSubgridCUDA2D(12,u,i);
+				//__syncthreads();
+				//caller->insertSubgridCUDA2D(u[l],i);
+				//__syncthreads();
+				//caller->getSubgridCUDA2D(i,caller, &u[l]);
+				caller->updateSubgridCUDA2D(i,caller, &u[l]);
+				__syncthreads();
+			}
+
+
+
+
+
+
+
+
+
+
+
+
+		}
+		/*if( bound )
+		{
+			caller->runSubgridCUDA2D(15,u,i);
+			__syncthreads();
+			//caller->insertSubgridCUDA2D(u[l],i);
+			//__syncthreads();
+			//caller->getSubgridCUDA2D(i,caller, &u[l]);
+			caller->updateSubgridCUDA2D(i,caller, &u[l]);
+			__syncthreads();
+		}*/
+
+		if(l==0)
+		{
+			caller->setBoundaryConditionCUDA2D(i, 0);
+			caller->setSubgridValueCUDA2D(i, caller->getSubgridValueCUDA2D(i) - 1 );
+		}
+
+
+	}
+
+
+
+}
+
+#endif /*HAVE_CUDA*/
+
+#endif /* TNLPARALLELEIKONALSOLVER2D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0871824cbf67f7ef18d276903ec84d8eeb0a109
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h
@@ -0,0 +1,1706 @@
+/***************************************************************************
+                          tnlParallelEikonalSolver2D_impl.h  -  description
+                             -------------------
+    begin                : Nov 28 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 TNLPARALLELEIKONALSOLVER3D_IMPL_H_
+#define TNLPARALLELEIKONALSOLVER3D_IMPL_H_
+
+
+#include "tnlParallelEikonalSolver.h"
+#include <core/mfilename.h>
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelEikonalSolver()
+{
+	cout << "a" << endl;
+	this->device = TNL::Devices::HostDevice;  /////////////// tnlCuda Device --- vypocet na GPU, TNL::Devices::HostDevice   ---    vypocet na CPU
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+	run_host = 1;
+	}
+#endif
+
+	cout << "b" << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::test()
+{
+/*
+	for(int i =0; i < this->subgridValues.getSize(); i++ )
+	{
+		insertSubgrid(getSubgrid(i), i);
+	}
+*/
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+
+bool tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters )
+{
+	cout << "Initializating solver..." << endl;
+	const String& meshLocation = parameters.getParameter <String>("mesh");
+	this->mesh.load( meshLocation );
+
+	this->n = parameters.getParameter <int>("subgrid-size");
+	cout << "Setting N to " << this->n << endl;
+
+	this->subMesh.setDimensions( this->n, this->n, this->n );
+	this->subMesh.setDomain( Containers::StaticVector<3,double>(0.0, 0.0, 0.0),
+							 Containers::StaticVector<3,double>(mesh.template getSpaceStepsProducts< 1, 0, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1, 0 >()*(double)(this->n),mesh.template getSpaceStepsProducts< 0, 0, 1 >()*(double)(this->n)) );
+
+	this->subMesh.save("submesh.tnl");
+
+	const String& initialCondition = parameters.getParameter <String>("initial-condition");
+	this->u0.load( initialCondition );
+
+	//cout << this->mesh.getCellCenter(0) << endl;
+
+	this->delta = parameters.getParameter <double>("delta");
+	this->delta *= mesh.template getSpaceStepsProducts< 1, 0, 0 >()*mesh.template getSpaceStepsProducts< 0, 1, 0 >();
+
+	cout << "Setting delta to " << this->delta << endl;
+
+	this->tau0 = parameters.getParameter <double>("initial-tau");
+	cout << "Setting initial tau to " << this->tau0 << endl;
+	this->stopTime = parameters.getParameter <double>("stop-time");
+
+	this->cflCondition = parameters.getParameter <double>("cfl-condition");
+	this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0, 0 >()*mesh.template getSpaceStepsProducts< 0, 1, 0 >());
+	cout << "Setting CFL to " << this->cflCondition << endl;
+
+	stretchGrid();
+	this->stopTime /= (double)(this->gridCols);
+	this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0));
+	cout << "Setting stopping time to " << this->stopTime << endl;
+	//this->stopTime = 1.5*((double)(this->n))*parameters.getParameter <double>("stop-time")*mesh.template getSpaceStepsProducts< 1, 0, 0 >();
+	//cout << "Setting stopping time to " << this->stopTime << endl;
+
+	cout << "Initializating scheme..." << endl;
+	if(!this->schemeHost.init(parameters))
+	{
+		cerr << "SchemeHost failed to initialize." << endl;
+		return false;
+	}
+	cout << "Scheme initialized." << endl;
+
+	test();
+
+	VectorType* tmp = new VectorType[subgridValues.getSize()];
+
+
+#ifdef HAVE_CUDA
+
+	if(this->device == tnlCudaDevice)
+	{
+	/*cout << "Testing... " << endl;
+	if(this->device == tnlCudaDevice)
+	{
+	if( !initCUDA3D(parameters, gridRows, gridCols) )
+		return false;
+	}*/
+		//cout << "s" << endl;
+	cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >));
+	//cout << "s" << endl;
+	cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice);
+	//cout << "s" << endl;
+	double** tmpdev = NULL;
+	cudaMalloc(&tmpdev, sizeof(double*));
+	//double* tmpw;
+	cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double));
+	cudaMalloc(&(this->runcuda), sizeof(int));
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	int* tmpUC;
+	cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int));
+	cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice);
+
+	initCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	//cout << "s " << endl;
+	//cudaMalloc(&(cudaSolver->work_u_cuda), this->work_u.getSize()*sizeof(double));
+	double* tmpu = NULL;
+
+	cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost);
+	//printf("%p %p \n",tmpu,tmpw);
+	cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice);
+	cudaDeviceSynchronize();
+	TNL_CHECK_CUDA_DEVICE;
+	//cout << "s "<< endl;
+
+	}
+#endif
+
+	if(this->device == TNL::Devices::HostDevice)
+	{
+#ifdef HAVE_OPENMP
+#pragma omp parallel for num_threads(4) schedule(dynamic)
+#endif
+		for(int i = 0; i < this->subgridValues.getSize(); i++)
+		{
+			bool containsCurve = false;
+//			cout << "Working on subgrid " << i <<" --- check 1" << endl;
+
+			if(! tmp[i].setSize(this->n*this->n*this->n))
+				cout << "Could not allocate tmp["<< i <<"] array." << endl;
+//			cout << "Working on subgrid " << i <<" --- check 2" << endl;
+
+			tmp[i] = getSubgrid(i);
+			containsCurve = false;
+//			cout << "Working on subgrid " << i <<" --- check 3" << endl;
+
+
+			for(int j = 0; j < tmp[i].getSize(); j++)
+			{
+				if(tmp[i][0]*tmp[i][j] <= 0.0)
+				{
+					containsCurve = true;
+					j=tmp[i].getSize();
+//					cout << tmp[i][0] << " " << tmp[i][j] << endl;
+				}
+
+			}
+//			cout << "Working on subgrid " << i <<" --- check 4" << endl;
+
+			if(containsCurve)
+			{
+//				cout << "Computing initial SDF on subgrid " << i << "." << endl;
+				tmp[i] = runSubgrid(0, tmp[i] ,i);
+				insertSubgrid( tmp[i], i);
+				setSubgridValue(i, 4);
+//				cout << "Computed initial SDF on subgrid " << i  << "." << endl;
+			}
+			containsCurve = false;
+
+		}
+//		cout << "CPU: Curve found" << endl;
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+//		cout << "pre 1 kernel" << endl;
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		dim3 threadsPerBlock(this->n, this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		initRunCUDA3D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,2*this->n*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+//		cout << "post 1 kernel" << endl;
+
+	}
+#endif
+
+
+	this->currentStep = 1;
+	if(this->device == TNL::Devices::HostDevice)
+		synchronize();
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		dim3 threadsPerBlock(this->n, this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels);
+		//double * test = (double*)malloc(this->work_u.getSize()*sizeof(double));
+		//cout << test[0] <<"   " << test[1] <<"   " << test[2] <<"   " << test[3] << endl;
+		//cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->tmpw << "   " <<  test[0] <<"   " << test[1] << "   " <<test[2] << "   " <<test[3] << endl;
+
+		TNL_CHECK_CUDA_DEVICE;
+
+		synchronizeCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+		cout << cudaGetErrorString(cudaDeviceSynchronize()) << endl;
+		TNL_CHECK_CUDA_DEVICE;
+		synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cout << test[0] << "   " <<test[1] <<"   " << test[2] << "   " <<test[3] << endl;
+		//cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//TNL_CHECK_CUDA_DEVICE;
+		//cout << this->tmpw << "   " <<  test[0] << "   " <<test[1] << "   " <<test[2] <<"   " << test[3] << endl;
+		//free(test);
+
+	}
+
+#endif
+	cout << "Solver initialized." << endl;
+
+	return true;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::run()
+{
+	if(this->device == TNL::Devices::HostDevice)
+	{
+
+	bool end = false;
+	while (/*(this->boundaryConditions.max() > 0 ) ||*/ !end)
+	{
+		if(this->boundaryConditions.max() == 0 || this->subgridValues.max() < 0)
+			end=true;
+		else
+			end=false;
+#ifdef HAVE_OPENMP
+#pragma omp parallel for num_threads(4) schedule(dynamic)
+#endif
+		for(int i = 0; i < this->subgridValues.getSize(); i++)
+		{
+			VectorType tmp;
+			tmp.setSize(this->n*this->n*this->n);
+			if(getSubgridValue(i) != INT_MAX)
+			{
+				//cout << "subMesh: " << i << ", BC: " << getBoundaryCondition(i) << endl;
+
+				if(getSubgridValue(i) == currentStep+4)
+				{
+
+					if(getBoundaryCondition(i) & 1)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(1, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+					if(getBoundaryCondition(i) & 2)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(2, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+					if(getBoundaryCondition(i) & 4)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(4, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+					if(getBoundaryCondition(i) & 8)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(8, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+					if(getBoundaryCondition(i) & 16)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(16, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+					if(getBoundaryCondition(i) & 32)
+					{
+						tmp = getSubgrid(i);
+						tmp = runSubgrid(32, tmp ,i);
+						insertSubgrid( tmp, i);
+						this->calculationsCount[i]++;
+					}
+				}
+
+				if( getBoundaryCondition(i) & 19)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(19, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 21)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(21, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 26)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(26, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 28)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(28, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+
+				if( getBoundaryCondition(i) & 35)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(35, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 37)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(37, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 42)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(42, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+				if( getBoundaryCondition(i) & 44)
+				{
+					tmp = getSubgrid(i);
+					tmp = runSubgrid(44, tmp ,i);
+					insertSubgrid( tmp, i);
+				}
+
+
+				setBoundaryCondition(i, 0);
+				setSubgridValue(i, getSubgridValue(i)-1);
+
+			}
+		}
+		synchronize();
+	}
+	}
+#ifdef HAVE_CUDA
+	else if(this->device == tnlCudaDevice)
+	{
+		//cout << "fn" << endl;
+		bool end_cuda = false;
+		dim3 threadsPerBlock(this->n, this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cudaMalloc(&runcuda,sizeof(bool));
+		//cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice);
+		//cout << "fn" << endl;
+		bool* tmpb;
+		//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+		//cudaDeviceSynchronize();
+		//TNL_CHECK_CUDA_DEVICE;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		TNL_CHECK_CUDA_DEVICE;
+		//cout << "fn" << endl;
+		int i = 1;
+		time_diff = 0.0;
+		while (run_host || !end_cuda)
+		{
+			cout << "Computing at step "<< i++ << endl;
+			if(run_host != 0 )
+				end_cuda = true;
+			else
+				end_cuda = false;
+			//cout << "a" << endl;
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			start = std::clock();
+			runCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,2*this->n*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+			//cout << "a" << endl;
+			cudaDeviceSynchronize();
+			time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+			//start = std::clock();
+			synchronizeCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			TNL_CHECK_CUDA_DEVICE;
+			//time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC);
+
+
+			//cout << "a" << endl;
+			//run_host = false;
+			//cout << "in kernel loop" << run_host << endl;
+			//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+			cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost);
+			//cout << "in kernel loop" << run_host << endl;
+		}
+		cout << "Solving time was: " << time_diff << endl;
+		//cout << "b" << endl;
+
+		//double* tmpu;
+		//cudaMemcpy(tmpu, &(cudaSolver->work_u_cuda),sizeof(double*), cudaMemcpyHostToDevice);
+		//cudaMemcpy(this->work_u.getData(), tmpu, this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->work_u.getData()[0] << endl;
+
+		//double * test = (double*)malloc(this->work_u.getSize()*sizeof(double));
+		//cout << test[0] << test[1] << test[2] << test[3] << endl;
+		cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost);
+		//cout << this->tmpw << "   " <<  test[0] << test[1] << test[2] << test[3] << endl;
+		//free(test);
+
+		cudaDeviceSynchronize();
+	}
+#endif
+	contractGrid();
+	this->u0.save("u-00001.tnl");
+	cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl;
+	cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl;
+	cout << "Solver finished" << endl;
+
+#ifdef HAVE_CUDA
+	if(this->device == tnlCudaDevice)
+	{
+		cudaFree(this->runcuda);
+		cudaFree(this->tmpw);
+		cudaFree(this->cudaSolver);
+	}
+#endif
+
+}
+
+//north - 1, east - 2, west - 4, south - 8
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+	cout << "Synchronizig..." << endl;
+	int tmp1, tmp2;
+	int grid1, grid2;
+
+//	if(this->currentStep & 1)
+//	{
+		for(int j = 0; j < this->gridRows - 1; j++)
+		{
+			for (int i = 0; i < this->gridCols*this->n; i++)
+			{
+				for (int k = 0; k < this->gridLevels*this->n; k++)
+				{
+//					cout << "a" << endl;
+					tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i + k*this->gridCols*this->n*this->gridRows*this->n;
+//					cout << "b" << endl;
+					tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i + k*this->gridCols*this->n*this->gridRows*this->n;
+//					cout << "c" << endl;
+					if(tmp1 > work_u.getSize())
+						cout << "tmp1: " << tmp1 << " x: " << j <<" y: " << i <<" z: " << k << endl;
+					if(tmp2 > work_u.getSize())
+						cout << "tmp2: " << tmp2 << " x: " << j <<" y: " << i <<" z: " << k << endl;
+					grid1 = getSubgridValue(getOwner(tmp1));
+//					cout << "d" << endl;
+					grid2 = getSubgridValue(getOwner(tmp2));
+//					cout << "e" << endl;
+					if(getOwner(tmp1)==getOwner(tmp2))
+						cout << "i, j, k" << i << "," << j << "," << k << endl;
+					if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+					{
+						this->work_u[tmp2] = this->work_u[tmp1];
+//						cout << "f" << endl;
+						this->unusedCell[tmp2] = 0;
+//						cout << "g" << endl;
+						if(grid2 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp2), -INT_MAX);
+						}
+//						cout << "h" << endl;
+						if(! (getBoundaryCondition(getOwner(tmp2)) & 8) )
+							setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8);
+//						cout << "i" << endl;
+					}
+					else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+					{
+						this->work_u[tmp1] = this->work_u[tmp2];
+//						cout << "j" << endl;
+						this->unusedCell[tmp1] = 0;
+//						cout << "k" << endl;
+						if(grid1 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp1), -INT_MAX);
+						}
+//						cout << "l" << endl;
+						if(! (getBoundaryCondition(getOwner(tmp1)) & 1) )
+							setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1);
+//						cout << "m" << endl;
+					}
+				}
+			}
+		}
+
+//	}
+//	else
+//	{
+
+		cout << "sync 2" << endl;
+		for(int i = 1; i < this->gridCols; i++)
+		{
+			for (int j = 0; j < this->gridRows*this->n; j++)
+			{
+				for (int k = 0; k < this->gridLevels*this->n; k++)
+				{
+					tmp1 = this->gridCols*this->n*j + i*this->n - 1 + k*this->gridCols*this->n*this->gridRows*this->n;
+					tmp2 = this->gridCols*this->n*j + i*this->n + k*this->gridCols*this->n*this->gridRows*this->n;
+					grid1 = getSubgridValue(getOwner(tmp1));
+					grid2 = getSubgridValue(getOwner(tmp2));
+					if(getOwner(tmp1)==getOwner(tmp2))
+						cout << "i, j, k" << i << "," << j << "," << k << endl;
+					if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+					{
+						this->work_u[tmp2] = this->work_u[tmp1];
+						this->unusedCell[tmp2] = 0;
+						if(grid2 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp2), -INT_MAX);
+						}
+						if(! (getBoundaryCondition(getOwner(tmp2)) & 4) )
+							setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4);
+					}
+					else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+					{
+						this->work_u[tmp1] = this->work_u[tmp2];
+						this->unusedCell[tmp1] = 0;
+						if(grid1 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp1), -INT_MAX);
+						}
+						if(! (getBoundaryCondition(getOwner(tmp1)) & 2) )
+							setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2);
+					}
+				}
+			}
+		}
+
+		cout << "sync 3" << endl;
+
+		for(int k = 1; k < this->gridLevels; k++)
+		{
+			for (int j = 0; j < this->gridRows*this->n; j++)
+			{
+				for (int i = 0; i < this->gridCols*this->n; i++)
+				{
+					tmp1 = this->gridCols*this->n*j + i + (k*this->n-1)*this->gridCols*this->n*this->gridRows*this->n;
+					tmp2 = this->gridCols*this->n*j + i + k*this->n*this->gridCols*this->n*this->gridRows*this->n;
+					grid1 = getSubgridValue(getOwner(tmp1));
+					grid2 = getSubgridValue(getOwner(tmp2));
+					if(getOwner(tmp1)==getOwner(tmp2))
+						cout << "i, j, k" << i << "," << j << "," << k << endl;
+					if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX))
+					{
+						this->work_u[tmp2] = this->work_u[tmp1];
+						this->unusedCell[tmp2] = 0;
+						if(grid2 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp2), -INT_MAX);
+						}
+						if(! (getBoundaryCondition(getOwner(tmp2)) & 32) )
+							setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+32);
+					}
+					else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX))
+					{
+						this->work_u[tmp1] = this->work_u[tmp2];
+						this->unusedCell[tmp1] = 0;
+						if(grid1 == INT_MAX)
+						{
+							setSubgridValue(getOwner(tmp1), -INT_MAX);
+						}
+						if(! (getBoundaryCondition(getOwner(tmp1)) & 16) )
+							setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+16);
+					}
+				}
+			}
+		}
+//		}
+
+
+
+	this->currentStep++;
+	int stepValue = this->currentStep + 4;
+	for (int i = 0; i < this->subgridValues.getSize(); i++)
+	{
+		if( getSubgridValue(i) == -INT_MAX )
+			setSubgridValue(i, stepValue);
+	}
+
+	cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl;
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const
+{
+
+	int j = i % (this->gridCols*this->gridRows*this->n*this->n);
+
+	return ( (i / (this->gridCols*this->gridRows*this->n*this->n*this->n))*this->gridCols*this->gridRows
+			+ (j / (this->gridCols*this->n*this->n))*this->gridCols
+			+ (j % (this->gridCols*this->n))/this->n);
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const
+{
+	return this->subgridValues[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value)
+{
+	this->subgridValues[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const
+{
+	return this->boundaryConditions[i];
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value)
+{
+	this->boundaryConditions[i] = value;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid()
+{
+	cout << "Stretching grid..." << endl;
+
+
+	this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) );
+	this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) );
+	this->gridLevels = ceil( ((double)(this->mesh.getDimensions().z()-1)) / ((double)(this->n-1)) );
+
+	//this->gridCols = (this->mesh.getDimensions().x()-1) / (this->n-1) ;
+	//this->gridRows = (this->mesh.getDimensions().y()-1) / (this->n-1) ;
+
+	cout << "Setting gridCols to " << this->gridCols << "." << endl;
+	cout << "Setting gridRows to " << this->gridRows << "." << endl;
+	cout << "Setting gridLevels to " << this->gridLevels << "." << endl;
+
+	this->subgridValues.setSize(this->gridCols*this->gridRows*this->gridLevels);
+	this->subgridValues.setValue(0);
+	this->boundaryConditions.setSize(this->gridCols*this->gridRows*this->gridLevels);
+	this->boundaryConditions.setValue(0);
+	this->calculationsCount.setSize(this->gridCols*this->gridRows*this->gridLevels);
+	this->calculationsCount.setValue(0);
+
+	for(int i = 0; i < this->subgridValues.getSize(); i++ )
+	{
+		this->subgridValues[i] = INT_MAX;
+		this->boundaryConditions[i] = 0;
+	}
+
+	int levelSize = this->n*this->n*this->gridCols*this->gridRows;
+	int stretchedSize = this->n*levelSize*this->gridLevels;
+
+	if(!this->work_u.setSize(stretchedSize))
+		cerr << "Could not allocate memory for stretched grid." << endl;
+	if(!this->unusedCell.setSize(stretchedSize))
+		cerr << "Could not allocate memory for supporting stretched grid." << endl;
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+
+
+
+	for(int i = 0; i < levelSize; i++)
+	{
+		int diff =(this->n*this->gridCols) - idealStretch ;
+
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if(i%(this->n*this->gridCols) - idealStretch  >= 0)
+		{
+			k+= i%(this->n*this->gridCols) - idealStretch +1 ;
+		}
+
+		if(i/(this->n*this->gridCols) - idealStretch + 1  > 0)
+		{
+			k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ;
+		}
+
+		for( int j = 0; j<this->n*this->gridLevels; j++)
+		{
+			this->unusedCell[i+j*levelSize] = 1;
+			int l = j/this->n;
+
+			if(j - idealStretch  >= 0)
+			{
+				l+= j - idealStretch + 1;
+			}
+
+			this->work_u[i+j*levelSize] = this->u0[i+(j-l)*mesh.getDimensions().x()*mesh.getDimensions().y()-k];
+		}
+
+	}
+
+
+
+	cout << "Grid stretched." << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::contractGrid()
+{
+	cout << "Contracting grid..." << endl;
+	int levelSize = this->n*this->n*this->gridCols*this->gridRows;
+	int stretchedSize = this->n*levelSize*this->gridLevels;
+
+	int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1);
+	cout << idealStretch << endl;
+
+
+	for(int i = 0; i < levelSize; i++)
+	{
+		int diff =(this->n*this->gridCols) - idealStretch ;
+		int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff;
+
+		if((i%(this->n*this->gridCols) - idealStretch  < 0) && (i/(this->n*this->gridCols) - idealStretch + 1  <= 0) )
+		{
+			for( int j = 0; j<this->n*this->gridLevels; j++)
+			{
+				int l = j/this->n;
+				if(j - idealStretch  < 0)
+					this->u0[i+(j-l)*mesh.getDimensions().x()*mesh.getDimensions().y()-k] = this->work_u[i+j*levelSize];
+			}
+		}
+
+	}
+
+	cout << "Grid contracted" << endl;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const
+{
+
+	VectorType u;
+	u.setSize(this->n*this->n*this->n);
+
+	int idx, idy, idz;
+	idz = i / (gridRows*this->gridCols);
+	idy = (i % (this->gridRows*this->gridCols)) / this->gridCols;
+	idx = i %  (this->gridCols);
+
+	for( int j = 0; j < this->n; j++)
+	{
+	//	int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n);
+		for( int k = 0; k < this->n; k++)
+		{
+			for( int l = 0; l < this->n; l++)
+			{
+				int index = (idz*this->n + l) * this->n*this->n*this->gridCols*this->gridRows
+						 + (idy) * this->n*this->n*this->gridCols
+						 + (idx) * this->n
+						 + k * this->n*this->gridCols
+						 + j;
+
+				u[j + k*this->n  + l*this->n*this->n] = this->work_u[ index ];
+			}
+		}
+	}
+	return u;
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i )
+{
+	int idx, idy, idz;
+	idz = i / (this->gridRows*this->gridCols);
+	idy = (i % (this->gridRows*this->gridCols)) / this->gridCols;
+	idx = i %  (this->gridCols);
+
+	for( int j = 0; j < this->n; j++)
+	{
+	//	int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n);
+		for( int k = 0; k < this->n; k++)
+		{
+			for( int l = 0; l < this->n; l++)
+			{
+
+				int index = (idz*this->n + l) * this->n*this->n*this->gridCols*this->gridRows
+						 + (idy) * this->n*this->n*this->gridCols
+						 + (idx) * this->n
+						 + k * this->n*this->gridCols
+						 + j;
+
+				//OMP LOCK index
+//				cout<< idx << " " << idy << " " << idz << " " << j << " " << k << " " << l << " " << idz << " " << unusedCell.getSize() << " " << u.getSize() << " " << index <<endl;
+				if( (fabs(this->work_u[index]) > fabs(u[j + k*this->n  + l*this->n*this->n])) || (this->unusedCell[index] == 1) )
+				{
+					this->work_u[index] = u[j + k*this->n  + l*this->n*this->n];
+					this->unusedCell[index] = 0;
+				}
+				//OMP UNLOCK index
+			}
+		}
+	}
+}
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+typename tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::VectorType
+tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID)
+{
+
+	VectorType fu;
+
+	fu.setLike(u);
+	fu.setValue( 0.0 );
+
+
+	bool tmp = false;
+	for(int i = 0; i < u.getSize(); i++)
+	{
+		if(u[0]*u[i] <= 0.0)
+			tmp=true;
+	}
+	int idx,idy,idz;
+	idz = subGridID / (this->gridRows*this->gridCols);
+	idy = (subGridID % (this->gridRows*this->gridCols)) / this->gridCols;
+	idx = subGridID %  (this->gridCols);
+	int centerGID = (this->n*idy + (this->n>>1) )*(this->n*this->gridCols) + this->n*idx + (this->n>>1)
+			      + ((this->n>>1)+this->n*idz)*this->n*this->n*this->gridRows*this->gridCols;
+	if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0)
+		tmp = true;
+	//if(this->currentStep + 3 < getSubgridValue(subGridID))
+		//tmp = true;
+
+
+	double value = sign(u[0]) * u.absMax();
+
+	if(tmp)
+	{}
+
+
+	//north - 1, east - 2, west - 4, south - 8
+	else if(boundaryCondition == 4)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j = 1;j < this->n; j++)
+				for(int k = 0;k < this->n; k++)
+				//if(fabs(u[i*this->n + j]) <  fabs(u[i*this->n]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[i*this->n];
+	}
+	else if(boundaryCondition == 2)
+	{
+		for(int i = 0; i < this->n; i++)
+			for(int j =0 ;j < this->n -1; j++)
+				for(int k = 0;k < this->n; k++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[(i+1)*this->n - 1];
+	}
+	else if(boundaryCondition == 1)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 0;i < this->n - 1; i++)
+				for(int k = 0;k < this->n; k++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[j + this->n*(this->n - 1)];
+	}
+	else if(boundaryCondition == 8)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 1;i < this->n; i++)
+				for(int k = 0;k < this->n; k++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[j];
+	}
+	else if(boundaryCondition == 16)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 0;i < this->n ; i++)
+				for(int k = 0;k < this->n-1; k++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[j + this->n*(this->n - 1)];
+	}
+	else if(boundaryCondition == 32)
+	{
+		for(int j = 0; j < this->n; j++)
+			for(int i = 0;i < this->n; i++)
+				for(int k = 1;k < this->n; k++)
+				//if(fabs(u[i*this->n + j]) < fabs(u[j]))
+				u[k*this->n*this->n + i*this->n + j] = value;// u[j];
+	}
+
+
+   double time = 0.0;
+   double currentTau = this->tau0;
+   double finalTime = this->stopTime;// + 3.0*(u.max() - u.min());
+   if(boundaryCondition == 0) finalTime *= 2.0;
+   if( time + currentTau > finalTime ) currentTau = finalTime - time;
+
+   double maxResidue( 1.0 );
+   //double lastResidue( 10000.0 );
+   tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+   while( time < finalTime /*|| maxResidue > subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*/)
+   {
+      /****
+       * Compute the RHS
+       */
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+//    	  cout << "i: " << i << ", time: " << time <<endl;
+    	  Containers::StaticVector<3,int> coords(i % subMesh.getDimensions().x(),
+    	  								(i % (subMesh.getDimensions().x()*subMesh.getDimensions().y())) / subMesh.getDimensions().x(),
+    	  								i / (subMesh.getDimensions().x()*subMesh.getDimensions().y()));
+//    	  	cout << "b " << i << " " << i % subMesh.getDimensions().x() << " " << (i % (subMesh.getDimensions().x()*subMesh.getDimensions().y())) << " " << (i % subMesh.getDimensions().x()*subMesh.getDimensions().y()) / subMesh.getDimensions().x() << " " << subMesh.getDimensions().x()*subMesh.getDimensions().y() << " " <<endl;
+			Entity.setCoordinates(coords);
+//			cout <<"c" << coords << endl;
+			Entity.refresh();
+//			cout << "d" <<endl;
+			neighborEntities.refresh(subMesh,Entity.getIndex());
+//			cout << "e" <<endl;
+    	  fu[ i ] = schemeHost.getValue( this->subMesh, i, coords,u, time, boundaryCondition, neighborEntities );
+//    	  cout << "f" <<endl;
+      }
+      maxResidue = fu. absMax();
+
+
+      if( this -> cflCondition * maxResidue != 0.0)
+    	  currentTau =  this -> cflCondition / maxResidue;
+
+     /* if (maxResidue < 0.05)
+    	  cout << "Max < 0.05" << endl;*/
+      if(currentTau > 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >())
+    	  currentTau = 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >();
+      /*if(maxResidue > lastResidue)
+    	  currentTau *=(1.0/10.0);*/
+
+
+      if( time + currentTau > finalTime ) currentTau = finalTime - time;
+//      for( int i = 0; i < fu.getSize(); i ++ )
+//      {
+//    	  //cout << "Too big RHS! i = " << i << ", fu = " << fu[i] << ", u = " << u[i] << endl;
+//    	  if((u[i]+currentTau * fu[ i ])*u[i] < 0.0 && fu[i] != 0.0 && u[i] != 0.0 )
+//    		  currentTau = fabs(u[i]/(2.0*fu[i]));
+//
+//      }
+
+
+      for( int i = 0; i < fu.getSize(); i ++ )
+      {
+    	  double add = u[i] + currentTau * fu[ i ];
+    	  //if( fabs(u[i]) < fabs(add) or (this->subgridValues[subGridID] == this->currentStep +4) )
+    		  u[ i ] = add;
+      }
+      time += currentTau;
+
+      //cout << '\r' << flush;
+     //cout << maxResidue << "   " << currentTau << " @ " << time << flush;
+     //lastResidue = maxResidue;
+   }
+   //cout << "Time: " << time << ", Res: " << maxResidue <<endl;
+	/*if (u.max() > 0.0)
+		this->stopTime /=(double) this->gridCols;*/
+
+//	VectorType solution;
+//	solution.setLike(u);
+//    for( int i = 0; i < u.getSize(); i ++ )
+//  	{
+//    	solution[i]=u[i];
+//   	}
+//	return solution;
+	return u;
+}
+
+
+#ifdef HAVE_CUDA
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA3D( const int i ,tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+	//int j = threadIdx.x + threadIdx.y * blockDim.x;
+//	int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows
+//			 + (blockIdx.y) * this->n*this->n*this->gridCols
+//             + (blockIdx.x) * this->n
+//             + threadIdx.y * this->n*this->gridCols
+//             + threadIdx.x;
+
+
+	int index =  blockDim.x*blockIdx.x + threadIdx.x +
+			  (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x +
+			  (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y;
+
+	//printf("i= %d,j= %d,th= %d\n",i,j,th);
+	*a = caller->work_u_cuda[index];
+	//printf("Hi %f \n", *a);
+	//return ret;
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA3D( const int i ,tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a)
+{
+//	int j = threadIdx.x + threadIdx.y * blockDim.x;
+//	int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows
+//			 + (blockIdx.y) * this->n*this->n*this->gridCols
+//             + (blockIdx.x) * this->n
+//             + threadIdx.y * this->n*this->gridCols
+//             + threadIdx.x;
+
+	int index =  blockDim.x*blockIdx.x + threadIdx.x +
+			  (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x +
+			  (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y;
+
+	if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) )
+	{
+		caller->work_u_cuda[index] = *a;
+		caller->unusedCell_cuda[index] = 0;
+
+	}
+
+	*a = caller->work_u_cuda[index];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA3D( double u, const int i )
+{
+
+
+//	int j = threadIdx.x + threadIdx.y * blockDim.x;
+	//printf("j = %d, u = %f\n", j,u);
+
+//		int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows
+//				 + (blockIdx.y) * this->n*this->n*this->gridCols
+//	             + (blockIdx.x) * this->n
+//	             + threadIdx.y * this->n*this->gridCols
+//	             + threadIdx.x;
+
+		int index =  blockDim.x*blockIdx.x + threadIdx.x +
+				  (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x +
+				  (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y;
+
+		//printf("i= %d,j= %d,index= %d\n",i,j,index);
+		if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) )
+		{
+			this->work_u_cuda[index] = u;
+			this->unusedCell_cuda[index] = 0;
+
+		}
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA3D( int boundaryCondition, double* u, int subGridID)
+{
+
+	__shared__ int tmp;
+	__shared__ double value;
+	//double tmpRes = 0.0;
+	volatile double* sharedTau = &u[blockDim.x*blockDim.y*blockDim.z];
+//	volatile double* absVal = &u[2*blockDim.x*blockDim.y*blockDim.z];
+	int i = threadIdx.x;
+	int j = threadIdx.y;
+	int k = threadIdx.z;
+	int l = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z*blockDim.x*blockDim.y;
+	bool computeFU = !((i == 0 && (boundaryCondition & 4)) or
+			 (i == blockDim.x - 1 && (boundaryCondition & 2)) or
+			 (j == 0 && (boundaryCondition & 8)) or
+			 (j == blockDim.y - 1  && (boundaryCondition & 1))or
+			 (k == 0 && (boundaryCondition & 32)) or
+			 (k == blockDim.z - 1  && (boundaryCondition & 16)));
+
+	if(l == 0)
+	{
+		tmp = 0;
+		int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1) )*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1)
+				      + ((blockDim.z>>1)+blockDim.z*blockIdx.z)*blockDim.x*blockDim.y*gridDim.x*gridDim.y;
+		if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0)
+			tmp = 1;
+	}
+	__syncthreads();
+
+
+	__syncthreads();
+	if(tmp !=1)
+	{
+//		if(computeFU)
+//			absVal[l]=0.0;
+//		else
+//			absVal[l] = fabs(u[l]);
+//
+//		__syncthreads();
+//
+//	      if((blockDim.x == 16) && (l < 128))		absVal[l] = Max(absVal[l],absVal[l+128]);
+//	      __syncthreads();
+//	      if((blockDim.x == 16) && (l < 64))		absVal[l] = Max(absVal[l],absVal[l+64]);
+//	      __syncthreads();
+//	      if(l < 32)    							absVal[l] = Max(absVal[l],absVal[l+32]);
+//	      if(l < 16)								absVal[l] = Max(absVal[l],absVal[l+16]);
+//	      if(l < 8)									absVal[l] = Max(absVal[l],absVal[l+8]);
+//	      if(l < 4)									absVal[l] = Max(absVal[l],absVal[l+4]);
+//	      if(l < 2)									absVal[l] = Max(absVal[l],absVal[l+2]);
+//	      if(l < 1)									value   = sign(u[0])*Max(absVal[l],absVal[l+1]);
+//		__syncthreads();
+//
+//		if(computeFU)
+//			u[l] = value;
+		if(computeFU)
+		{
+			tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Ent(subMesh);
+			if(boundaryCondition == 4)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(0,j,k));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.x) ;//+  2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.x+this->n);
+			}
+			else if(boundaryCondition == 2)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(blockDim.x - 1,j,k));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(this->n - 1 - threadIdx.x);//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(blockDim.x - threadIdx.x - 1+this->n);
+			}
+			else if(boundaryCondition == 8)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(i,0,k));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 1, 0 >()*(threadIdx.y) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.y+this->n);
+			}
+			else if(boundaryCondition == 1)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(i,blockDim.y - 1,k));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 1, 0 >()*(this->n - 1 - threadIdx.y) ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(blockDim.y - threadIdx.y  - 1 +this->n);
+			}
+			else if(boundaryCondition == 32)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(i,j,0));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 0, 1 >()*(threadIdx.z);
+			}
+			else if(boundaryCondition == 16)
+			{
+				Ent.setCoordinates(Containers::StaticVector<3,int>(i,j,blockDim.z - 1));
+			   	Ent.refresh();
+				u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 0, 1 >()*(this->n - 1 - threadIdx.z) ;
+			}
+		}
+	}
+
+   double time = 0.0;
+   __shared__ double currentTau;
+   double cfl = this->cflCondition;
+   double fu = 0.0;
+//   if(threadIdx.x * threadIdx.y * threadIdx.z == 0)
+//   {
+//	   currentTau = this->tau0;
+//   }
+   double finalTime = this->stopTime;
+   __syncthreads();
+   if( boundaryCondition == 0 ) finalTime *= 2.0;
+
+   tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Entity(subMesh);
+   tnlNeighborGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighborEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<3,int>(i,j,k));
+   Entity.refresh();
+   neighborEntities.refresh(subMesh,Entity.getIndex());
+
+
+   while( time < finalTime )
+   {
+	  sharedTau[l]=finalTime;
+
+	  if(computeFU)
+	  {
+		  fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<3,int>(i,j,k), u, time, boundaryCondition, neighborEntities);
+		  if(abs(fu) > 0.0)
+			  sharedTau[l]=abs(cfl/fu);
+	  }
+
+      if(l == 0)
+      {
+    	  if(sharedTau[0] > 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >())	sharedTau[0] = 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >();
+      }
+      else if(l == blockDim.x*blockDim.y*blockDim.z - 1)
+      {
+    	  if( time + sharedTau[l] > finalTime )		sharedTau[l] = finalTime - time;
+      }
+
+      __syncthreads();
+      if(l < 256)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+256]);
+      __syncthreads();
+      if(l < 128)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]);
+      __syncthreads();
+      if(l < 64)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]);
+      __syncthreads();
+      if(l < 32)    							sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]);
+      __syncthreads();
+      if(l < 16)								sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]);
+      if(l < 8)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]);
+      if(l < 4)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]);
+      if(l < 2)									sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]);
+      if(l < 1)									currentTau   = Min(sharedTau[l],sharedTau[l+1]);
+      __syncthreads();
+
+//	if(abs(fu) < 10000.0)
+//		printf("bla");
+      if(computeFU)
+    	  u[l] += currentTau * fu;
+      time += currentTau;
+      __syncthreads();
+   }
+
+
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA3D(int i) const
+{
+	int j = i % (this->gridCols*this->gridRows*this->n*this->n);
+
+	return ( (i / (this->gridCols*this->gridRows*this->n*this->n))*this->gridCols*this->gridRows
+			+ (j / (this->gridCols*this->n*this->n))*this->gridCols
+			+ (j % (this->gridCols*this->n))/this->n);
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA3D( int i ) const
+{
+	return this->subgridValues_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA3D(int i, int value)
+{
+	this->subgridValues_cuda[i] = value;
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA3D( int i ) const
+{
+	return this->boundaryConditions_cuda[i];
+}
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__device__
+void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA3D(int i, int value)
+{
+	this->boundaryConditions_cuda[i] = value;
+}
+
+
+
+//north - 1, east - 2, west - 4, south - 8, up -16, down - 32
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void /*tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::*/synchronizeCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now
+{
+
+	__shared__ int boundary[6]; // north,east,west,south
+	__shared__ int subgridValue;
+	__shared__ int newSubgridValue;
+
+
+	int gid =  blockDim.x*blockIdx.x + threadIdx.x +
+			  (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x +
+			  (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y;
+	double u = cudaSolver->work_u_cuda[gid];
+	double u_cmp;
+	int subgridValue_cmp=INT_MAX;
+	int boundary_index=0;
+
+
+	if(threadIdx.x+threadIdx.y+threadIdx.z == 0)
+	{
+		subgridValue = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y);
+		boundary[0] = 0;
+		boundary[1] = 0;
+		boundary[2] = 0;
+		boundary[3] = 0;
+		boundary[4] = 0;
+		boundary[5] = 0;
+		newSubgridValue = 0;
+//		printf("aaa z = %d, y = %d, x = %d\n",blockIdx.z,blockIdx.y,blockIdx.x);
+	}
+	__syncthreads();
+
+
+
+	if(		(threadIdx.x == 0 				/*				&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == 0 				 	/*			&& (cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.z == 0 	 /*	&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.x == blockDim.x - 1 	 /*	&& !(cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.y == blockDim.y - 1 	 /*	&& (cudaSolver->currentStep & 1)*/) 		||
+			(threadIdx.z == blockDim.z - 1 	 /*	&& (cudaSolver->currentStep & 1)*/) 		)
+	{
+		if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y - 1);
+			boundary_index = 2;
+		}
+
+		if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + 1];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y + 1);
+			boundary_index = 1;
+		}
+
+		__threadfence();
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+			u=u_cmp;
+		}
+		__threadfence();
+		if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D((blockIdx.y - 1)*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y);
+			boundary_index = 3;
+		}
+		if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D((blockIdx.y + 1)*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y);
+			boundary_index = 0;
+		}
+
+		__threadfence();
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+			u=u_cmp;
+		}
+		__threadfence();
+
+		if(threadIdx.z == 0 && (blockIdx.z != 0)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x*blockDim.y*gridDim.y];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + (blockIdx.z - 1)*gridDim.x*gridDim.y);
+			boundary_index = 5;
+		}
+		if(threadIdx.z == blockDim.z - 1 && (blockIdx.z != gridDim.z - 1)/* && (cudaSolver->currentStep & 1)*/)
+		{
+			u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x*blockDim.y*gridDim.y];
+			subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + (blockIdx.z + 1)*gridDim.x*gridDim.y);
+			boundary_index = 4;
+		}
+		__threadfence();
+
+		if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX))
+		{
+			cudaSolver->unusedCell_cuda[gid] = 0;
+			atomicMax(&newSubgridValue, INT_MAX);
+			atomicMax(&boundary[boundary_index], 1);
+			cudaSolver->work_u_cuda[gid] = u_cmp;
+		}
+		__threadfence();
+
+	}
+	__syncthreads();
+
+	if(threadIdx.x+threadIdx.y+threadIdx.z == 0)
+	{
+
+		if(subgridValue == INT_MAX && newSubgridValue != 0)
+			cudaSolver->setSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y, -INT_MAX);
+
+		cudaSolver->setBoundaryConditionCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y, 	1  * boundary[0] +
+																													2  * boundary[1] +
+																													4  * boundary[2] +
+																													8  * boundary[3] +
+																													16 * boundary[4] +
+																													32 * boundary[5] );
+		if(blockIdx.x+blockIdx.y+blockIdx.z == 0)
+		{
+			cudaSolver->currentStep = cudaSolver->currentStep + 1;
+			*(cudaSolver->runcuda) = 0;
+		}
+	}
+}
+
+
+
+template <typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void synchronize2CUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver)
+{
+	int stepValue = cudaSolver->currentStep + 4;
+	if( cudaSolver->getSubgridValueCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX )
+			cudaSolver->setSubgridValueCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x, stepValue);
+
+	atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x));
+}
+
+
+
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device>
+__global__
+void initCUDA3D( tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3)
+{
+
+
+	cudaSolver->work_u_cuda = ptr;//(double*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(double));
+	cudaSolver->unusedCell_cuda = ptr3;//(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(int));
+	cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels*sizeof(int));
+	cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels*sizeof(int));
+	cudaSolver->runcuda = ptr2;//(bool*)malloc(sizeof(bool));
+	*(cudaSolver->runcuda) = 1;
+	cudaSolver->currentStep = 1;
+	//cudaMemcpy(ptr,&(cudaSolver->work_u_cuda), sizeof(double*),cudaMemcpyDeviceToHost);
+	//ptr = cudaSolver->work_u_cuda;
+	printf("GPU memory allocated.\n");
+
+	for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels; i++)
+	{
+		cudaSolver->subgridValues_cuda[i] = INT_MAX;
+		cudaSolver->boundaryConditions_cuda[i] = 0;
+	}
+
+	/*for(long int j = 0; j < cudaSolver->n*cudaSolver->n*cudaSolver->gridCols*cudaSolver->gridRows; j++)
+	{
+		printf("%d\n",j);
+		cudaSolver->unusedCell_cuda[ j] = 1;
+	}*/
+	printf("GPU memory initialized.\n");
+}
+
+
+
+
+//extern __shared__ double array[];
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void initRunCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller)
+
+{
+
+
+	extern __shared__ double u[];
+
+	int i =  blockIdx.z *  gridDim.x *  gridDim.y +  blockIdx.y *  gridDim.x +  blockIdx.x;
+	int l = threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x;
+
+	__shared__ int containsCurve;
+	if(l == 0)
+	{
+//		printf("z = %d, y = %d, x = %d\n",blockIdx.z,blockIdx.y,blockIdx.x);
+		containsCurve = 0;
+	}
+
+	caller->getSubgridCUDA3D(i,caller, &u[l]);
+	__syncthreads();
+	if(u[0] * u[l] <= 0.0)
+	{
+		atomicMax( &containsCurve, 1);
+	}
+
+	__syncthreads();
+	if(containsCurve == 1)
+	{
+		caller->runSubgridCUDA3D(0,u,i);
+		__syncthreads();
+//		caller->insertSubgridCUDA3D(u[l],i);
+		caller->updateSubgridCUDA3D(i,caller, &u[l]);
+
+		__syncthreads();
+		if(l == 0)
+			caller->setSubgridValueCUDA3D(i, 4);
+	}
+
+
+}
+
+
+
+
+
+template< typename SchemeHost, typename SchemeDevice, typename Device >
+__global__
+void runCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller)
+{
+	extern __shared__ double u[];
+	int i =  blockIdx.z *  gridDim.x *  gridDim.y +  blockIdx.y *  gridDim.x +  blockIdx.x;
+	int l = threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x;
+	int bound = caller->getBoundaryConditionCUDA3D(i);
+
+	if(caller->getSubgridValueCUDA3D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA3D(i) > 0)
+	{
+		caller->getSubgridCUDA3D(i,caller, &u[l]);
+
+		//if(l == 0)
+			//printf("i = %d, bound = %d\n",i,caller->getSubgridValueCUDA3D(i));
+		if(caller->getSubgridValueCUDA3D(i) == caller->currentStep+4)
+		{
+			if(bound & 1)
+			{
+				caller->runSubgridCUDA3D(1,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 2 )
+			{
+				caller->runSubgridCUDA3D(2,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 4)
+			{
+				caller->runSubgridCUDA3D(4,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 8)
+			{
+				caller->runSubgridCUDA3D(8,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 16)
+			{
+				caller->runSubgridCUDA3D(16,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound & 32)
+			{
+				caller->runSubgridCUDA3D(32,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+
+		}
+		else
+		{
+			if( ((bound == 2)))
+			{
+				caller->runSubgridCUDA3D(2,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if( ((bound == 1) ))
+			{
+				caller->runSubgridCUDA3D(1,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if( ((bound == 8) ))
+			{
+				caller->runSubgridCUDA3D(8,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if((bound == 4))
+			{
+				caller->runSubgridCUDA3D(4,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound == 16)
+			{
+				caller->runSubgridCUDA3D(16,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+			if(bound == 32)
+			{
+				caller->runSubgridCUDA3D(32,u,i);
+				caller->updateSubgridCUDA3D(i,caller, &u[l]);
+				__syncthreads();
+			}
+		}
+																/*  1  2  4  8  16  32  */
+
+		if( ((bound & 19 )))									/*  1  1  0  0   1   0  */
+		{
+			caller->runSubgridCUDA3D(19,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if( ((bound & 21 )))									/*  1  0  1  0   1   0  */
+		{
+			caller->runSubgridCUDA3D(21,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if( ((bound & 26 )))									/*  0  1  0  1   1   0  */
+		{
+			caller->runSubgridCUDA3D(26,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if(   (bound & 28 ))									/*  0  0  1  1   1   0  */
+		{
+			caller->runSubgridCUDA3D(28,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+
+
+
+		if( ((bound & 35 )))									/*  1  0  1  0   0   1  */
+		{
+			caller->runSubgridCUDA3D(35,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if( ((bound & 37 )))									/*  1  0  1  0   0   1  */
+		{
+			caller->runSubgridCUDA3D(37,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if( ((bound & 42 )))									/*  0  1  0  1   0   1  */
+		{
+			caller->runSubgridCUDA3D(42,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+		if(   (bound & 44 ))									/*  0  0  1  1   0   1  */
+		{
+			caller->runSubgridCUDA3D(44,u,i);
+			caller->updateSubgridCUDA3D(i,caller, &u[l]);
+			__syncthreads();
+		}
+
+		if(l==0)
+		{
+			caller->setBoundaryConditionCUDA3D(i, 0);
+			caller->setSubgridValueCUDA3D(i, caller->getSubgridValueCUDA3D(i) - 1 );
+		}
+
+
+	}
+
+
+
+}
+
+#endif /*HAVE_CUDA*/
+
+#endif /* TNLPARALLELEIKONALSOLVER3D_IMPL_H_ */
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..04348b8b5baa4bdbd772b67feaf9da3b32aed53d
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt
@@ -0,0 +1,21 @@
+set( tnl_hamilton_jacobi_SOURCES
+     hamiltonJacobiProblemSetter.h
+     hamiltonJacobiProblemSetter_impl.h
+     hamiltonJacobiProblemSolver.h
+     hamiltonJacobiProblemSolver_impl.h
+     main.cpp
+     hamiltonJacobiProblemConfig.h
+     tnl-direct-eikonal-solver.h )
+               
+ADD_EXECUTABLE(tnl-hamilton-jacobi${debugExt} main.cpp)
+target_link_libraries (tnl-hamilton-jacobi${debugExt} tnl${debugExt}-${tnlVersion} )
+
+ADD_EXECUTABLE(tnl-direct-eikonal-solver${debugExt} tnl-direct-eikonal-solver.cpp )
+target_link_libraries (tnl-direct-eikonal-solver${debugExt} tnl${debugExt}-${tnlVersion} )
+
+
+INSTALL( TARGETS tnl-hamilton-jacobi${debugExt} 
+                 tnl-direct-eikonal-solver${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..0523f7e90e1ccd0cef6683ffcff34b324305eee7
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h
@@ -0,0 +1,97 @@
+/***************************************************************************
+                          hamiltonJacobiProblem.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once
+
+#include <problems/tnlPDEProblem.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/tnlSolverMonitor.h>
+#include <core/tnlLogger.h>
+#include <TNL/Containers/Vector.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+		    typename DifferentialOperator,
+		    typename BoundaryCondition,
+		    typename RightHandSide>
+class HamiltonJacobiProblem : public tnlPDEProblem< Mesh,
+                                                    TimeDependentProblem,
+                                                    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, TimeDependentProblem, RealType, DeviceType, IndexType > BaseType;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+
+      static String getTypeStatic();
+
+      String getPrologHeader() const;
+
+      void writeProlog( tnlLogger& logger,
+                        const Config::ParameterContainer& parameters ) const;
+
+      bool setup( const Config::ParameterContainer& parameters );
+
+      bool setInitialCondition( const Config::ParameterContainer& parameters,
+                                const MeshType& mesh,
+                                DofVectorType& dofs,
+                                MeshDependentDataType& meshDependentData );
+
+      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 getExplicitUpdate( const RealType& time,
+                           const RealType& tau,
+                           const MeshType& mesh,
+                           DofVectorType& _u,
+                           DofVectorType& _fu,
+                           MeshDependentDataType& meshDependentData );
+
+   protected:
+
+      MeshFunctionType solution;
+
+      tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide  > explicitUpdater;
+
+      DifferentialOperator differentialOperator;
+
+      BoundaryCondition boundaryCondition;
+
+      RightHandSide rightHandSide;
+};
+
+#include "HamiltonJacobiProblem_impl.h"
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e84c7d98966b3e35d86e263850a7df14d85ff13
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+                          hamiltonJacobiProblemConfig.h  -  description
+                             -------------------
+    begin                : Oct 5, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+    email                :
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <config/tnlConfigDescription.h>
+
+template< typename ConfigTag >
+class HamiltonJacobiProblemConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Hamilton-Jacobi solver settings:" );
+         config.addEntry        < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi" );
+         config.addEntry       < String > ( "scheme", "This defines scheme used for discretization.", "godunov" );
+         config.addEntryEnum( "godunov" );
+         config.addEntryEnum( "upwind" );
+         config.addEntry        < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 3.0 );
+         config.addEntry        < double > ( "-value", "Constant value of RHS.", 0.0 );
+      }
+};
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce4209736e95d6e58e410cc2acef09c1542270b8
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+                          hamiltonJacobiProblemSetter.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <TNL/Config/ParameterContainer.h>
+#include "HamiltonJacobiProblem.h"
+
+template< typename RealType,
+		  typename DeviceType,
+		  typename IndexType,
+		  typename MeshType,
+		  typename ConfigTag,
+          typename SolverStarter >
+class HamiltonJacobiProblemSetter
+{
+   public:
+   static bool run( const Config::ParameterContainer& parameters );
+};
+
+#include "HamiltonJacobiProblemSetter_impl.h"
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..5639cf32e4bc18e9f3a06d0c370f00f7acc742c4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+                          hamiltonJacobiProblemSetter_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlConstantFunction.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/hamilton-jacobi/upwindEikonal.h>
+#include <operators/hamilton-jacobi/godunovEikonal.h>
+#include <operators/hamilton-jacobi/tnlEikonalOperator.h>
+
+
+template< typename RealType,
+          typename DeviceType,
+          typename IndexType,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+bool HamiltonJacobiProblemSetter< RealType, DeviceType, IndexType, MeshType, ConfigTag, SolverStarter > :: run( const Config::ParameterContainer& parameters )
+{
+   static const int Dimensions = MeshType::getMeshDimension();
+
+   if( Dimensions <= 0 || Dimensions > 3 )
+   {
+      cerr << "The problem is not defined for " << Dimensions << "dimensions." << endl;
+      return false;
+   }
+   else
+   {
+      typedef Containers::StaticVector < Dimensions, RealType > Point;
+      typedef tnlConstantFunction< Dimensions, RealType > ConstantFunctionType;
+      typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunctionType, RealType, IndexType > BoundaryConditions;
+
+      SolverStarter solverStarter;
+
+      const String& schemeName = parameters.getParameter< String >( "scheme" );
+
+      if( schemeName == "upwind" )
+      {
+           typedef upwindEikonalScheme< MeshType, RealType, IndexType > GradientNormOperator;
+           typedef tnlConstantFunction< Dimensions, RealType > RightHandSide;
+           typedef tnlEikonalOperator< GradientNormOperator, RightHandSide > Operator;
+           typedef HamiltonJacobiProblem< MeshType, Operator, BoundaryConditions, RightHandSide > Solver;
+           return solverStarter.template run< Solver >( parameters );
+      }
+      if( schemeName == "godunov" )
+      {
+           typedef godunovEikonalScheme< MeshType, RealType, IndexType > GradientNormOperator;
+           typedef tnlConstantFunction< Dimensions, RealType > RightHandSide;
+           typedef tnlEikonalOperator< GradientNormOperator, RightHandSide > Operator;
+           typedef HamiltonJacobiProblem< MeshType, Operator, BoundaryConditions, RightHandSide > Solver;
+           return solverStarter.template run< Solver >( parameters );
+      }      
+      else
+         cerr << "Unknown scheme '" << schemeName << "'." << endl;
+
+
+      return false;
+   }
+}
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ff998c72789028dea441991e6f10568c36c80bf
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h
@@ -0,0 +1,199 @@
+/***************************************************************************
+                          HamiltonJacobiProblem_impl.h  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <exception>
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+String HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: getTypeStatic()
+{
+   return String( "hamiltonJacobiSolver< " ) + Mesh  :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+String HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: getPrologHeader() const
+{
+   return String( "Hamilton-Jacobi" );
+}
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+void HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: writeProlog( tnlLogger& logger,
+                                                												 const Config::ParameterContainer& parameters ) const
+{
+   //logger. WriteParameter< typename String >( "Problem name:", "problem-name", parameters );
+   //logger. WriteParameter< String >( "Used scheme:", "scheme", parameters );
+}
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+bool HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: setup( const Config::ParameterContainer& parameters )
+{
+   this->boundaryCondition.getFunction().setConstant( 1.0 );
+   //this->rightHandSide.getFunction().setConstant( 0.0 );
+   //return true;
+/*
+   const String& problemName = parameters. GetParameter< String >( "problem-name" );
+
+   this->schemeTest = parameters. GetParameter< int >( "scheme-test" );
+   this->tested = false;
+
+   const String& meshFile = parameters.GetParameter< String >( "mesh" );
+   if( ! this->mesh.load( meshFile ) )
+   {
+	   cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+	   return false;
+   }
+
+   const IndexType& dofs = this->mesh.getDofs();
+   dofVector. setSize( dofs );
+
+   this -> u. bind( & dofVector. getData()[ 0 * dofs ], dofs );
+   this -> v. bind( & dofVector. getData()[ 1 * dofs ], dofs );
+
+*/
+   differentialOperator.getAnisotropy().setConstant( 1.0 ); //setup( parameters );
+   differentialOperator.setSmoothing( 1.0 );
+   return true;
+
+}
+
+
+template< typename Mesh,
+          typename HamiltonJacobi,
+          typename BoundaryCondition,
+          typename RightHandSide>
+typename HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::IndexType
+         HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Set-up DOFs and supporting grid functions
+    */
+   return mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename HamiltonJacobi,
+          typename BoundaryCondition,
+          typename RightHandSide>
+void HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+   //const IndexType dofs = mesh.template getEntitiesCount< typename MeshType::Cell >();
+   this->solution.bind( mesh, dofVector );
+}
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+bool
+HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::
+setInitialCondition( const Config::ParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData  )
+{
+   this->bindDofs( mesh, dofs );
+   const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
+   if( ! this->solution.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 HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+bool 
+HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::
+makeSnapshot( const RealType& time,
+              const IndexType& step,
+              const MeshType& mesh,
+              DofVectorType& dofs,
+              MeshDependentDataType& meshDependentData  )
+{
+   cout << endl << "Writing output at time " << time << " step " << step << "." << endl;
+
+   String fileName;
+   FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
+   if( ! this->solution.save( fileName ) )
+	   return false;
+
+   return true;
+}
+
+
+template< typename Mesh,
+		  typename HamiltonJacobi,
+		  typename BoundaryCondition,
+		  typename RightHandSide>
+void
+HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::
+getExplicitUpdate(  const RealType& time,
+                 const RealType& tau,
+                 const MeshType& mesh,
+                 DofVectorType& _u,
+                 DofVectorType& _fu,
+                 MeshDependentDataType& meshDependentData  )
+{
+
+	/*
+	if(!(this->schemeTest))
+		scheme.getExplicitUpdate(time, tau, _u, _fu);
+	else if(!(this->tested))
+	{
+		this->tested = true;
+		DofVectorType tmp;
+		if(tmp.setLike(_u))
+			tmp = _u;
+		scheme.getExplicitUpdate(time, tau, tmp, _u);
+
+	}
+	*/
+
+	//this->bindDofs( mesh, _u );
+   MeshFunctionType u, fu;
+   u.bind( mesh, _u );
+   fu.bind( mesh, _fu );
+   explicitUpdater.template update< typename MeshType::Cell >( time,
+	                                                            mesh,
+	                                                            this->differentialOperator,
+	                                                            this->boundaryCondition,
+	                                                            this->rightHandSide,
+	                                                            u,
+	                                                            fu );
+   //fu.save( "fu.tnl" );
+   //std::cerr << "Enter." << std::endl;
+   //getchar();
+}
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          MainBuildConfig.h  -  description
+                             -------------------
+    begin                : Jul 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef MAINBUILDCONFIG_H_
+#define MAINBUILDCONFIG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class MainBuildConfig
+{
+   public:
+
+      static void print() { cerr << "MainBuildConfig" << endl; }
+};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled  &&
+                         tnlConfigTagReal< MainBuildConfig, Real >::enabled &&
+                         tnlConfigTagDevice< MainBuildConfig, Device >::enabled &&
+                         tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; };
+template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* MAINBUILDCONFIG_H_ */
diff --git a/examples/mean-curvature-flow/Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile
similarity index 55%
rename from examples/mean-curvature-flow/Makefile
rename to src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile
index 71873be3fbafbf131bd8b092c7078a9dea9b167d..03620692c53d343adcb0e73060dba775223b1c7c 100644
--- a/examples/mean-curvature-flow/Makefile
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile
@@ -1,36 +1,41 @@
-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) $<
+TNL_VERSION=0.1
+TNL_INSTALL_DIR=${HOME}/local/lib
+TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION}
+
+TARGET = hamiltonJacobiSolver
+CONFIG_FILE = $(TARGET).cfg.desc
+INSTALL_DIR = ${HOME}/local
+CXX = g++
+CUDA_CXX = nvcc
+OMP_FLAGS = -DHAVE_OPENMP -fopenmp
+CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS)
+LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp
+
+SOURCES = main.cpp
+HEADERS = 
+OBJECTS = main.o
+DIST = $(SOURCES) Makefile
+
+all: $(TARGET)
+clean: 
+	rm -f $(OBJECTS)
+	rm -f $(TARGET)-conf.h	
+
+dist: $(DIST)
+	tar zcvf $(TARGET).tgz $(DIST) 
+
+install: $(TARGET)
+	cp $(TARGET) $(INSTALL_DIR)/bin
+	cp $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+uninstall: $(TARGET)
+	rm -f $(INSTALL_DIR)/bin/$(TARGET) 
+	rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share
+
+$(TARGET): $(OBJECTS)
+	$(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS)
+
+%.o: %.cpp $(HEADERS)
+	$(CXX) -c -o $@ $(CXX_FLAGS) $<
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3c6af1c9e610f76d67cc903c66d55c7f07b5f4ee
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp
@@ -0,0 +1,33 @@
+/***************************************************************************
+                          main.cpp  -  description
+                             -------------------
+    begin                : Jul 8 , 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "HamiltonJacobiProblemConfig.h"
+#include "HamiltonJacobiProblemSetter.h"
+#include <solvers/tnlSolver.h>
+#include "MainBuildConfig.h"
+#include <solvers/tnlBuildConfigTags.h>
+
+typedef MainBuildConfig BuildConfig;
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< HamiltonJacobiProblemSetter, HamiltonJacobiProblemConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4343837617b4c0c1416b209b6f755fcaf1476912
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp
@@ -0,0 +1,14 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnl-direct-eikonal-solver.cpp
+ * Author: oberhuber
+ *
+ * Created on July 13, 2016, 1:13 PM
+ */
+
+#include "tnl-direct-eikonal-solver.h"
\ No newline at end of file
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu
new file mode 100644
index 0000000000000000000000000000000000000000..21b17dbdd425c1bb4c6a9664a1c7ba7e2df6d0c4
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu
@@ -0,0 +1,14 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnl-direct-eikonal-solver.cu
+ * Author: oberhuber
+ *
+ * Created on July 13, 2016, 1:13 PM
+ */
+
+#include "tnl-direct-eikonal-solver.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h
new file mode 100644
index 0000000000000000000000000000000000000000..b453d0e6a909c9145e07d674267167e9e8dda213
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h
@@ -0,0 +1,72 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnl-direct-eikonal-solver.h
+ * Author: oberhuber
+ *
+ * Created on July 13, 2016, 1:09 PM
+ */
+
+#pragma once
+
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlFastBuildConfigTag.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <functions/tnlConstantFunction.h>
+#include <functions/tnlMeshFunction.h>
+//#include <problems/tnlHeatEquationProblem.h>
+#include <mesh/tnlGrid.h>
+#include "tnlDirectEikonalProblem.h"
+
+//typedef tnlDefaultBuildMeshConfig BuildConfig;
+typedef tnlFastBuildConfig BuildConfig;
+
+template< typename MeshConfig >
+class tnlDirectEikonalSolverConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Direct eikonal equation solver settings:" );
+         config.addRequiredEntry< String >( "input-file", "Input file." );
+      };
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename MeshConfig,
+          typename SolverStarter >
+class tnlDirectEikonalSolverSetter
+{
+   public:
+
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef Containers::StaticVector< MeshType::meshDimensions, Real > Point;
+
+   static bool run( const Config::ParameterContainer& parameters )
+   {
+      enum { Dimensions = MeshType::meshDimensions };
+      typedef tnlConstantFunction< Dimensions, Real > Anisotropy;
+      typedef tnlDirectEikonalProblem< MeshType, Anisotropy > Problem;
+      SolverStarter solverStarter;
+      return solverStarter.template run< Problem >( parameters );
+   };
+};
+
+int main( int argc, char* argv[] )
+{
+   if( ! tnlSolver< tnlDirectEikonalSolverSetter, tnlDirectEikonalSolverConfig, BuildConfig >::run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test
new file mode 100644
index 0000000000000000000000000000000000000000..bcc05ef15adf4f042fe813d875545b2bae09096a
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test
@@ -0,0 +1,201 @@
+#!/bin/bash
+
+device="host"
+dimensions="1D 2D 3D"
+#dimensions="1D"
+sizes1D="16 32 64 128 256 512 1024 2048 4096"
+#sizes1D="256"
+sizes2D="16 32 64 128 256 512 1024"
+#sizes2D="8"
+sizes3D="16 32 64 128 256"
+testFunctions="paraboloid"
+snapshotPeriod=0.1
+finalTime=1.5
+solverName="tnl-hamilton-jacobi"
+#solverName="gdb --args tnl-hamilton-jacobi-dbg"
+#
+
+setupTestFunction()
+{
+   testFunction=$1
+#   if test x${testFunction} = "xexp-bump";
+#   then
+      origin=-1.0
+      proportions=2.0
+      amplitude=1.0
+      waveLength=0.2
+      waveLengthX=0.2
+      waveLengthY=0.2
+      waveLengthZ=0.2
+      wavesNumber=3.0
+      wavesNumberX=0.5
+      wavesNumberY=2.0
+      wavesNumberZ=3.0
+      phase=0.1
+      phaseX=0.0
+      phaseY=0.0
+      phaseZ=0.0
+      sigma=0.5
+#   fi
+}
+
+setupGrid()
+{
+   dimensions=$1
+   gridSize=$2
+   tnl-grid-setup --dimensions ${dimensions} \
+                  --origin-x ${origin} \
+                  --origin-y ${origin} \
+                  --origin-z ${origin} \
+                  --proportions-x ${proportions} \
+                  --proportions-y ${proportions} \
+                  --proportions-z ${proportions} \
+                  --size-x ${gridSize} \
+                  --size-y ${gridSize} \
+                  --size-z ${gridSize} 
+}
+
+setInitialCondition()
+{
+   testFunction=$1
+   tnl-init --test-function ${testFunction} \
+            --output-file initial-u.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} 
+   
+    tnl-init --test-function ${testFunction}-sdf \
+            --output-file final-u.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma}
+
+}
+
+solve()
+{
+   timeDiscretisation=$1
+   discreteSolver=$2
+   ${solverName} --device ${device} \
+                 --mesh mesh.tnl \
+                 --initial-condition initial-u.tnl \
+                 --time-discretisation ${timeDiscretisation} \
+                 --time-step 10 \
+                 --time-step-order 2 \
+                 --discrete-solver ${discreteSolver} \
+                 --merson-adaptivity 1.0e-5 \
+                 --min-iterations 20 \
+                 --convergence-residue 1.0e-12 \
+                 --snapshot-period ${snapshotPeriod} \
+                 --final-time ${finalTime}
+}
+               
+computeError()
+{
+   tnl-diff --mesh mesh.tnl \
+            --input-files final-u.tnl u-*.tnl \
+            --mode sequence \
+            --snapshot-period ${snapshotPeriod} \
+            --output-file errors.txt \
+            --write-difference yes
+}
+
+runTest()
+{
+   for testFunction in ${testFunctions};
+   do
+      mkdir -p ${testFunction}
+      cd ${testFunction}
+      setupTestFunction ${testFunction}
+      
+      for dim in ${dimensions};
+      do
+         mkdir -p $dim
+         cd ${dim}
+         if test $dim = 1D;
+         then 
+            sizes=$sizes1D
+         fi
+         if test $dim = 2D;
+         then 
+            sizes=$sizes2D
+         fi
+         if test $dim = 3D;
+         then 
+            sizes=$sizes3D
+         fi
+         
+         lastSize=""
+         for size in $sizes;
+         do
+            mkdir -p $size
+            cd $size
+            echo ""
+            echo ""
+            echo ""
+            if test ! -f computation-done;
+            then
+               touch computation-in-progress
+               echo "========================================================================="
+               echo "===                   SETTING UP THE GRID                             ==="
+               echo "========================================================================="
+               setupGrid $dim $size 
+               echo "========================================================================="
+               echo "===                WRITING THE EXACT SOLUTION                         ==="
+               echo "========================================================================="
+               setInitialCondition $testFunction
+               echo "========================================================================="
+               echo "===                   STARTING THE SOLVER                             ==="
+               echo "========================================================================="
+               solve explicit merson
+               #solve semi-implicit gmres
+               mv computation-in-progress computation-done
+            fi            
+            echo "========================================================================="
+            echo "===                   COMPUTING THE ERROR                             ==="
+            echo "========================================================================="
+            computeError
+            echo "========================================================================="
+            echo "===                     COMPUTING THE EOC                             ==="            
+            echo "========================================================================="
+            if test ! x$lastSize = x;
+            then
+               tnl-err2eoc ../$lastSize/errors.txt errors.txt
+            fi
+            echo "========================================================================="
+            echo "===                     COMPUTATION DONE                              ==="            
+            echo "========================================================================="
+            cd ..
+            lastSize=$size
+         done
+
+         cd ..
+      done
+      cd ..
+   done
+}
+
+runTest
+ 
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test
new file mode 100755
index 0000000000000000000000000000000000000000..6d997ce230a9de4ad1deefc1ccaa1f926021a16f
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test
@@ -0,0 +1,204 @@
+#!/bin/bash
+
+device="host"
+dimensions="2D 3D"
+dimensions="2D"
+sizes1D="16 32 64 128 256 512 1024 2048 4096"
+#sizes1D="256"
+sizes2D="16 32 64 128 256 512 1024"
+#sizes2D="8"
+sizes3D="16 32 64 128 256"
+testFunctions="paraboloid"
+snapshotPeriod=0.1
+finalTime=1.5
+solverName="tnl-direct-eikonal-solver"
+#solverName="gdb --args tnl-direct-eikonal-solver-dbg"
+#
+
+setupTestFunction()
+{
+   testFunction=$1
+#   if test x${testFunction} = "xexp-bump";
+#   then
+      origin=-1.0
+      proportions=2.0
+      amplitude=1.0
+      waveLength=0.2
+      waveLengthX=0.2
+      waveLengthY=0.2
+      waveLengthZ=0.2
+      wavesNumber=3.0
+      wavesNumberX=0.5
+      wavesNumberY=2.0
+      wavesNumberZ=3.0
+      phase=0.1
+      phaseX=0.0
+      phaseY=0.0
+      phaseZ=0.0
+      sigma=0.5
+      radius=0.5
+#   fi
+}
+
+setupGrid()
+{
+   dimensions=$1
+   gridSize=$2
+   tnl-grid-setup --dimensions ${dimensions} \
+                  --origin-x ${origin} \
+                  --origin-y ${origin} \
+                  --origin-z ${origin} \
+                  --proportions-x ${proportions} \
+                  --proportions-y ${proportions} \
+                  --proportions-z ${proportions} \
+                  --size-x ${gridSize} \
+                  --size-y ${gridSize} \
+                  --size-z ${gridSize} 
+}
+
+setInitialCondition()
+{
+   testFunction=$1
+   tnl-init --test-function ${testFunction}-sdf \
+            --output-file initial-u.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} \
+            --radius ${radius}
+   
+    tnl-init --test-function ${testFunction}-sdf \
+            --output-file final-u.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} \
+            --radius ${radius}
+
+}
+
+solve()
+{
+   timeDiscretisation=$1
+   discreteSolver=$2
+   ${solverName} --device ${device} \
+                 --mesh mesh.tnl \
+                 --input-file initial-u.tnl \
+                 --time-discretisation ${timeDiscretisation} \
+                 --time-step 10 \
+                 --time-step-order 2 \
+                 --discrete-solver ${discreteSolver} \
+                 --merson-adaptivity 1.0e-5 \
+                 --min-iterations 20 \
+                 --convergence-residue 1.0e-12 \
+                 --snapshot-period ${snapshotPeriod} \
+                 --final-time ${finalTime}
+}
+               
+computeError()
+{
+   tnl-diff --mesh mesh.tnl \
+            --input-files final-u.tnl u-*.tnl \
+            --mode sequence \
+            --snapshot-period ${snapshotPeriod} \
+            --output-file errors.txt \
+            --write-difference yes
+}
+
+runTest()
+{
+   for testFunction in ${testFunctions};
+   do
+      mkdir -p ${testFunction}
+      cd ${testFunction}
+      setupTestFunction ${testFunction}
+      
+      for dim in ${dimensions};
+      do
+         mkdir -p $dim
+         cd ${dim}
+         if test $dim = 1D;
+         then 
+            sizes=$sizes1D
+         fi
+         if test $dim = 2D;
+         then 
+            sizes=$sizes2D
+         fi
+         if test $dim = 3D;
+         then 
+            sizes=$sizes3D
+         fi
+         
+         lastSize=""
+         for size in $sizes;
+         do
+            mkdir -p $size
+            cd $size
+            echo ""
+            echo ""
+            echo ""
+            if test ! -f computation-done;
+            then
+               touch computation-in-progress
+               echo "========================================================================="
+               echo "===                   SETTING UP THE GRID                             ==="
+               echo "========================================================================="
+               setupGrid $dim $size 
+               echo "========================================================================="
+               echo "===                WRITING THE EXACT SOLUTION                         ==="
+               echo "========================================================================="
+               setInitialCondition $testFunction
+               echo "========================================================================="
+               echo "===                   STARTING THE SOLVER                             ==="
+               echo "========================================================================="
+               solve explicit merson
+               #solve semi-implicit gmres
+               mv computation-in-progress computation-done
+            fi            
+            echo "========================================================================="
+            echo "===                   COMPUTING THE ERROR                             ==="
+            echo "========================================================================="
+            computeError
+            echo "========================================================================="
+            echo "===                     COMPUTING THE EOC                             ==="            
+            echo "========================================================================="
+            if test ! x$lastSize = x;
+            then
+               tnl-err2eoc ../$lastSize/errors.txt errors.txt
+            fi
+            echo "========================================================================="
+            echo "===                     COMPUTATION DONE                              ==="            
+            echo "========================================================================="
+            cd ..
+            lastSize=$size
+         done
+
+         cd ..
+      done
+      cd ..
+   done
+}
+
+runTest
+ 
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..409a2d93a1d7eb719e3b4f93b6eb9b7da53f72e5
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h
@@ -0,0 +1,89 @@
+/* 
+ * File:   tnlDirectEikonalMethodsBase.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 3:17 PM
+ */
+
+#pragma once 
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh >
+class tnlDirectEikonalMethodsBase
+{   
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef Device DevcieType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      typedef tnlMeshFunction< MeshType, 1, bool > InterfaceMapType;
+      
+      void initInterface( const MeshFunctionType& input,
+                          MeshFunctionType& output,
+                          InterfaceMapType& interfaceMap );
+      
+      template< typename MeshEntity >
+      void updateCell( MeshFunctionType& u,
+                       const MeshEntity& cell );
+      
+};
+
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef Device DevcieType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      typedef tnlMeshFunction< MeshType, 2, bool > InterfaceMapType;
+
+      void initInterface( const MeshFunctionType& input,
+                          MeshFunctionType& output,
+                          InterfaceMapType& interfaceMap );
+      
+      template< typename MeshEntity >
+      void updateCell( MeshFunctionType& u,
+                       const MeshEntity& cell );
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef Device DevcieType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      typedef tnlMeshFunction< MeshType, 3, bool > InterfaceMapType;
+
+      void initInterface( const MeshFunctionType& input,
+                          MeshFunctionType& output,
+                          InterfaceMapType& interfaceMap );
+      
+      template< typename MeshEntity >
+      void updateCell( MeshFunctionType& u,
+                       const MeshEntity& cell );      
+};
+
+#include "tnlDirectEikonalMethodsBase_impl.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b924f72331e7126f3d8accc7392e9e7554827890
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h
@@ -0,0 +1,233 @@
+/* 
+ * File:   tnlDirectEikonalMethodsBase_impl.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 3:22 PM
+ */
+
+#pragma once
+
+#include <core/tnlTypeInfo.h>
+#include <functions/tnlFunctions.h>
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >::
+initInterface( const MeshFunctionType& input,
+               MeshFunctionType& output,
+               InterfaceMapType& interfaceMap  )
+{
+   const MeshType& mesh = input.getMesh();
+   typedef typename MeshType::Cell Cell;
+   Cell cell( mesh );
+   for( cell.getCoordinates().x() = 1;
+        cell.getCoordinates().x() < mesh.getDimensions().x() - 1;
+        cell.getCoordinates().x() ++ )
+   {
+      cell.refresh();
+      const RealType& c = input( cell );      
+      if( ! cell.isBoundaryEntity()  )
+      {
+         const auto& neighbors = cell.getNeighborEntities();
+         //const IndexType& c = cell.getIndex();
+         const IndexType e = neighbors.template getEntityIndex<  1 >();
+         const IndexType w = neighbors.template getEntityIndex< -1 >();
+
+         if( c * input[ e ] <= 0 || c * input[ w ] <= 0 )
+         {
+            output[ cell.getIndex() ] = c;
+            interfaceMap[ cell.getIndex() ] = true;
+            continue;
+         }
+      }
+      output[ cell.getIndex() ] =
+      c > 0 ? tnlTypeInfo< RealType >::getMaxValue() :
+             -tnlTypeInfo< RealType >::getMaxValue();
+      interfaceMap[ cell.getIndex() ] = false;
+   }
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename MeshEntity >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >::
+updateCell( MeshFunctionType& u,
+            const MeshEntity& cell )
+{
+}
+
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >::
+initInterface( const MeshFunctionType& input,
+               MeshFunctionType& output,
+               InterfaceMapType& interfaceMap  )
+{
+   const MeshType& mesh = input.getMesh();
+   typedef typename MeshType::Cell Cell;
+   Cell cell( mesh );
+   for( cell.getCoordinates().y() = 0;
+        cell.getCoordinates().y() < mesh.getDimensions().y();
+        cell.getCoordinates().y() ++ )
+      for( cell.getCoordinates().x() = 0;
+           cell.getCoordinates().x() < mesh.getDimensions().x();
+           cell.getCoordinates().x() ++ )
+      {
+         cell.refresh();
+         const RealType& c = input( cell );
+         if( ! cell.isBoundaryEntity()  )
+         {
+            auto neighbors = cell.getNeighborEntities();
+            const IndexType e = neighbors.template getEntityIndex<  1,  0 >();
+            const IndexType w = neighbors.template getEntityIndex< -1,  0 >();
+            const IndexType n = neighbors.template getEntityIndex<  0,  1 >();
+            const IndexType s = neighbors.template getEntityIndex<  0, -1 >();            
+            if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ||
+                c * input[ n ] <= 0 || c * input[ s ] <= 0 )
+            {
+               output[ cell.getIndex() ] = c;
+               interfaceMap[ cell.getIndex() ] = true;
+               continue;
+            }
+         }
+         output[ cell.getIndex() ] =
+            c > 0 ? tnlTypeInfo< RealType >::getMaxValue() :
+                   -tnlTypeInfo< RealType >::getMaxValue();  
+         interfaceMap[ cell.getIndex() ] = false;
+      }
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename MeshEntity >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >::
+updateCell( MeshFunctionType& u,
+            const MeshEntity& cell )
+{
+   const auto& neighborEntities = cell.template getNeighborEntities< 2 >();
+   const MeshType& mesh = cell.getMesh();
+  
+   const RealType& h = mesh.getSpaceSteps().x(); 
+   const RealType value = u( cell );
+   Real a, b, tmp;
+
+   if( cell.getCoordinates().x() == 0 )
+      a = u[ neighborEntities.template getEntityIndex< 1,  0 >() ];
+   else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 )
+      a = u[ neighborEntities.template getEntityIndex< -1,  0 >() ];
+   else
+   {
+      a = ArgAbsMin( u[ neighborEntities.template getEntityIndex< -1,  0 >() ],
+                     u[ neighborEntities.template getEntityIndex<  1,  0 >() ] );
+   }
+
+   if( cell.getCoordinates().y() == 0 )
+      b = u[ neighborEntities.template getEntityIndex< 0,  1 >()];
+   else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 )
+      b = u[ neighborEntities.template getEntityIndex< 0,  -1 >() ];
+   else
+   {
+      b = ArgAbsMin( u[ neighborEntities.template getEntityIndex< 0,  -1 >() ],
+                     u[ neighborEntities.template getEntityIndex< 0,   1 >() ] );
+   }
+
+   if( fabs( a ) == tnlTypeInfo< Real >::getMaxValue() && 
+       fabs( b ) == tnlTypeInfo< Real >::getMaxValue() )
+      return;
+   if( fabs( a ) == tnlTypeInfo< Real >::getMaxValue() ||
+       fabs( b ) == tnlTypeInfo< Real >::getMaxValue() ||
+       fabs( a - b ) >= h )
+   {
+      tmp = ArgAbsMin( a, b ) + sign( value ) * h;
+      /*   std::cerr << "a = " << a << " b = " << b << " h = " << h 
+             << " ArgAbsMin( a, b ) = " << ArgAbsMin( a, b ) << " sign( value ) = " << sign( value )
+             << " sign( value ) * h = " << sign( value ) * h
+             << " ArgAbsMin( a, b ) + sign( value ) * h = " << ArgAbsMin( a, b ) + sign( value ) * h           
+             << " tmp = " << tmp << std::endl;
+      tmp = ArgAbsMin( a, b ) + sign( value ) * h;
+      tmp = ArgAbsMin( a, b ) + sign( value ) * h;
+      tmp = ArgAbsMin( a, b ) + sign( value ) * h;
+      res = ArgAbsMin( a, b ) + sign( value ) * h;
+      std::cerr << " tmp = " << tmp << std::endl;
+      std::cerr << " res = " << res << std::endl;*/
+
+   }
+   else
+      tmp = 0.5 * ( a + b + sign( value ) * sqrt( 2.0 * h * h - ( a - b ) * ( a - b ) ) );
+
+   u[ cell.getIndex() ] = ArgAbsMin( value, tmp );
+   //std::cerr << ArgAbsMin( value, tmp ) << " ";   
+}
+
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >::
+initInterface( const MeshFunctionType& input,
+               MeshFunctionType& output,
+               InterfaceMapType& interfaceMap  )
+{
+   const MeshType& mesh = input.getMesh();
+   typedef typename MeshType::Cell Cell;
+   Cell cell( mesh );
+   for( cell.getCoordinates().z() = 1;
+        cell.getCoordinates().z() < mesh.getDimensions().z() - 1;
+        cell.getCoordinates().z() ++ )   
+      for( cell.getCoordinates().y() = 1;
+           cell.getCoordinates().y() < mesh.getDimensions().y() - 1;
+           cell.getCoordinates().y() ++ )
+         for( cell.getCoordinates().x() = 1;
+              cell.getCoordinates().x() < mesh.getDimensions().x() - 1;
+              cell.getCoordinates().x() ++ )
+         {
+            cell.refresh();
+            const RealType& c = input( cell );
+            if( ! cell.isBoundaryEntity() )
+            {
+               auto neighbors = cell.getNeighborEntities();
+               //const IndexType& c = cell.getIndex();
+               const IndexType e = neighbors.template getEntityIndex<  1,  0,  0 >();
+               const IndexType w = neighbors.template getEntityIndex< -1,  0,  0 >();
+               const IndexType n = neighbors.template getEntityIndex<  0,  1,  0 >();
+               const IndexType s = neighbors.template getEntityIndex<  0, -1,  0 >();
+               const IndexType t = neighbors.template getEntityIndex<  0,  0,  1 >();
+               const IndexType b = neighbors.template getEntityIndex<  0,  0, -1 >();
+
+               if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ||
+                   c * input[ n ] <= 0 || c * input[ s ] <= 0 ||
+                   c * input[ t ] <= 0 || c * input[ b ] <= 0 )
+               {
+                  output[ cell.getIndex() ] = c;
+                  interfaceMap[ cell.getIndex() ] = true;
+                  continue;
+               }
+            }
+            output[ cell.getIndex() ] =
+               c > 0 ? tnlTypeInfo< RealType >::getMaxValue() :
+                      -tnlTypeInfo< RealType >::getMaxValue();
+            interfaceMap[ cell.getIndex() ] = false;
+         }
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename MeshEntity >
+void
+tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >::
+updateCell( MeshFunctionType& u,
+            const MeshEntity& cell )
+{
+   
+}
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..f4baba1528165a9ca95bf18b68eaebe09d0c7848
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h
@@ -0,0 +1,80 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod.h
+ * Author: oberhuber
+ *
+ * Created on July 13, 2016, 1:19 PM
+ */
+
+#pragma once
+
+#include <problems/tnlPDEProblem.h>
+#include <functions/tnlMeshFunction.h>
+#include "tnlFastSweepingMethod.h"
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlDirectEikonalProblem
+   : public tnlPDEProblem< Mesh,
+                           TimeIndependentProblem,
+                           Real,
+                           typename Mesh::DeviceType,
+                           Index  >
+{
+   public:
+   
+      typedef Real RealType;
+      typedef typename Mesh::DeviceType DeviceType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
+      typedef tnlPDEProblem< Mesh, TimeIndependentProblem, RealType, DeviceType, IndexType > BaseType;
+      typedef Anisotropy AnisotropyType;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+
+      static String getTypeStatic();
+
+      String getPrologHeader() const;
+
+      void writeProlog( tnlLogger& logger,
+                        const Config::ParameterContainer& parameters ) const;
+      
+      bool writeEpilog( tnlLogger& logger );
+
+
+      bool setup( const Config::ParameterContainer& parameters );
+
+      IndexType getDofs( const MeshType& mesh ) const;
+
+      void bindDofs( const MeshType& mesh,
+                     const DofVectorType& dofs );
+      
+      bool setInitialData( const Config::ParameterContainer& parameters,
+                           const MeshType& mesh,
+                           DofVectorType& dofs,
+                           MeshDependentDataType& meshdependentData );
+
+      bool solve( const MeshType& mesh,
+                  DofVectorType& dosf );
+
+
+      protected:
+         
+         MeshFunctionType u;
+         
+         MeshFunctionType initialData;
+         
+         AnisotropyType anisotropy;
+
+};
+
+#include "tnlDirectEikonalProblem_impl.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..9dcf2fb5fa40b49462bed8ced05b4ebf605c38d6
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h
@@ -0,0 +1,125 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod_impl.h
+ * Author: oberhuber
+ *
+ * Created on July 13, 2016, 1:46 PM
+ */
+
+#pragma once
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+String
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+getTypeStatic()
+{
+   
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+String
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+getPrologHeader() const
+{
+   return String( "Direct eikonal solver" );
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+void
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+writeProlog( tnlLogger& logger,
+             const Config::ParameterContainer& parameters ) const
+{
+   
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+bool
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+writeEpilog( tnlLogger& logger )
+{
+   return true;
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+bool
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+setup( const Config::ParameterContainer& parameters )
+{
+   return true;
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+Index
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+getDofs( const MeshType& mesh ) const
+{
+   return mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+void
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+bindDofs( const MeshType& mesh,
+          const DofVectorType& dofs )
+{
+   this->u.bind( mesh, dofs );
+}
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+bool
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+setInitialData( const Config::ParameterContainer& parameters,
+                const MeshType& mesh,
+                DofVectorType& dofs,
+                MeshDependentDataType& meshdependentData )
+{
+   String inputFile = parameters.getParameter< String >( "input-file" );
+   this->initialData.setMesh( mesh );
+   if( !this->initialData.boundLoad( inputFile ) )
+      return false;
+   return true;
+}
+
+
+template< typename Mesh,
+          typename Anisotropy,
+          typename Real,
+          typename Index >
+bool
+tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >::
+solve( const MeshType& mesh,
+       DofVectorType& dofs )
+{
+   tnlFastSweepingMethod< MeshType, AnisotropyType > fsm;
+   fsm.solve( mesh, anisotropy, initialData );
+}
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h
new file mode 100644
index 0000000000000000000000000000000000000000..59ddc2a690b5e6aecb62d5cf4c0997b7c567ff82
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h
@@ -0,0 +1,141 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 10:04 AM
+ */
+
+#pragma once
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlConstantFunction.h>
+#include "tnlDirectEikonalMethodsBase.h"
+
+template< typename Mesh,
+          typename Anisotropy = tnlConstantFunction< Mesh::getMeshDimension(), typename Mesh::RealType > >
+class tnlFastSweepingMethod
+{   
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+class tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >
+   : public tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >
+{
+   static_assert(  std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef TNL::Devices::Host DeviceType;
+      typedef Index IndexType;
+      typedef Anisotropy AnisotropyType;
+      typedef tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > > BaseType;
+      
+      using typename BaseType::InterfaceMapType;
+      using typename BaseType::MeshFunctionType;
+      
+      tnlFastSweepingMethod();
+      
+      const IndexType& getMaxIterations() const;
+      
+      void setMaxIterations( const IndexType& maxIterations );
+      
+      void solve( const MeshType& mesh,
+                  const AnisotropyType& anisotropy,
+                  MeshFunctionType& u );
+      
+      
+   protected:
+      
+      const IndexType maxIterations;
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+class tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >
+   : public tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >
+{
+   static_assert(  std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef TNL::Devices::Host DeviceType;
+      typedef Index IndexType;
+      typedef Anisotropy AnisotropyType;
+      typedef tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > > BaseType;
+
+      using typename BaseType::InterfaceMapType;
+      using typename BaseType::MeshFunctionType;
+
+      tnlFastSweepingMethod();
+      
+      const IndexType& getMaxIterations() const;
+      
+      void setMaxIterations( const IndexType& maxIterations );
+      
+      void solve( const MeshType& mesh,
+                  const AnisotropyType& anisotropy,
+                  MeshFunctionType& u );
+      
+      
+   protected:
+      
+      const IndexType maxIterations;
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+class tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >
+   : public tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >
+{
+   static_assert(  std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef TNL::Devices::Host DeviceType;
+      typedef Index IndexType;
+      typedef Anisotropy AnisotropyType;
+      typedef tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > > BaseType;
+      
+      using typename BaseType::InterfaceMapType;
+      using typename BaseType::MeshFunctionType;
+      
+      tnlFastSweepingMethod();
+      
+      const IndexType& getMaxIterations() const;
+      
+      void setMaxIterations( const IndexType& maxIterations );
+      
+      void solve( const MeshType& mesh,
+                  const AnisotropyType& anisotropy,
+                  MeshFunctionType& u );
+      
+      
+   protected:
+      
+      const IndexType maxIterations;
+};
+
+
+
+#include "tnlFastSweepingMethod1D_impl.h"
+#include "tnlFastSweepingMethod2D_impl.h"
+#include "tnlFastSweepingMethod3D_impl.h"
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..050bc6075454c3d23685f25a6e9d607b36c88d73
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h
@@ -0,0 +1,70 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod2D_impl.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 10:32 AM
+ */
+
+#pragma once
+
+#include "tnlFastSweepingMethod.h"
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >::
+tnlFastSweepingMethod()
+: maxIterations( 1 )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+const Index&
+tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >::
+getMaxIterations() const
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >::
+setMaxIterations( const IndexType& maxIterations )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >::
+solve( const MeshType& mesh,
+       const AnisotropyType& anisotropy,
+       MeshFunctionType& u )
+{
+   MeshFunctionType aux;
+   InterfaceMapType interfaceMap;
+   aux.setMesh( mesh );
+   interfaceMap.setMesh( mesh );
+   std::cout << "Initiating the interface cells ..." << std::endl;
+   BaseType::initInterface( u, aux, interfaceMap );
+   aux.save( "aux-ini.tnl" );
+
+}
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc2cfe9401c54aa7bff5e88f4c9d9ecf40f919cd
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h
@@ -0,0 +1,141 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod2D_impl.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 10:32 AM
+ */
+
+#pragma once
+
+#include "tnlFastSweepingMethod.h"
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >::
+tnlFastSweepingMethod()
+: maxIterations( 1 )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+const Index&
+tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >::
+getMaxIterations() const
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >::
+setMaxIterations( const IndexType& maxIterations )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >::
+solve( const MeshType& mesh,
+       const AnisotropyType& anisotropy,
+       MeshFunctionType& u )
+{
+   MeshFunctionType aux;
+   InterfaceMapType interfaceMap;
+   aux.setMesh( mesh );
+   interfaceMap.setMesh( mesh );
+   std::cout << "Initiating the interface cells ..." << std::endl;
+   BaseType::initInterface( u, aux, interfaceMap );
+   //aux.save( "aux-ini.tnl" );
+
+   typename MeshType::Cell cell( mesh );
+   
+   IndexType iteration( 0 );
+   while( iteration < this->maxIterations )
+   {
+
+      for( cell.getCoordinates().y() = 0;
+           cell.getCoordinates().y() < mesh.getDimensions().y();
+           cell.getCoordinates().y()++ )
+      {
+         for( cell.getCoordinates().x() = 0;
+              cell.getCoordinates().x() < mesh.getDimensions().x();
+              cell.getCoordinates().x()++ )
+            {
+               cell.refresh();
+               if( ! interfaceMap( cell ) )
+                  this->updateCell( aux, cell );
+            }
+      }
+      //aux.save( "aux-1.tnl" );
+
+      for( cell.getCoordinates().y() = 0;
+           cell.getCoordinates().y() < mesh.getDimensions().y();
+           cell.getCoordinates().y()++ )
+      {
+         for( cell.getCoordinates().x() = mesh.getDimensions().x() - 1;
+              cell.getCoordinates().x() >= 0 ;
+              cell.getCoordinates().x()-- )		
+            {
+               //std::cerr << "2 -> ";
+               cell.refresh();
+               if( ! interfaceMap( cell ) )            
+                  this->updateCell( aux, cell );
+            }
+      }
+      //aux.save( "aux-2.tnl" );
+
+      for( cell.getCoordinates().y() = mesh.getDimensions().y() - 1;
+           cell.getCoordinates().y() >= 0 ;
+           cell.getCoordinates().y()-- )
+         {
+         for( cell.getCoordinates().x() = 0;
+              cell.getCoordinates().x() < mesh.getDimensions().x();
+              cell.getCoordinates().x()++ )
+            {
+               //std::cerr << "3 -> ";
+               cell.refresh();
+               if( ! interfaceMap( cell ) )            
+                  this->updateCell( aux, cell );
+            }
+         }
+      //aux.save( "aux-3.tnl" );
+
+
+      for( cell.getCoordinates().y() = mesh.getDimensions().y() - 1;
+           cell.getCoordinates().y() >= 0;
+           cell.getCoordinates().y()-- )
+         {
+         for( cell.getCoordinates().x() = mesh.getDimensions().x() - 1;
+              cell.getCoordinates().x() >= 0 ;
+              cell.getCoordinates().x()-- )		
+            {
+               //std::cerr << "4 -> ";
+               cell.refresh();
+               if( ! interfaceMap( cell ) )            
+                  this->updateCell( aux, cell );
+            }
+         }   
+      //aux.save( "aux-4.tnl" );
+      iteration++;
+   }
+}
+
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f252537148b9968b1a84421da7ca563169525ae7
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h
@@ -0,0 +1,69 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   tnlFastSweepingMethod2D_impl.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 10:32 AM
+ */
+
+#pragma once
+
+#include "tnlFastSweepingMethod.h"
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >::
+tnlFastSweepingMethod()
+: maxIterations( 1 )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+const Index&
+tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >::
+getMaxIterations() const
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >::
+setMaxIterations( const IndexType& maxIterations )
+{
+   
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Anisotropy >
+void
+tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >::
+solve( const MeshType& mesh,
+       const AnisotropyType& anisotropy,
+       MeshFunctionType& u )
+{
+   MeshFunctionType aux;
+   InterfaceMapType interfaceMap;
+   aux.setMesh( mesh );
+   interfaceMap.setMesh( mesh );
+   std::cout << "Initiating the interface cells ..." << std::endl;
+   BaseType::initInterface( u, aux, interfaceMap );
+   aux.save( "aux-ini.tnl" );   
+}
+
diff --git a/src/TNL/Experimental/Multimaps/EllpackIndexMultimap_impl.h b/src/TNL/Experimental/Multimaps/EllpackIndexMultimap_impl.h
index 8a24c06cb247e86827290da94e26f60d8a27e6d0..1b7c41a937f3fd5b9cd92c600364f09d5b4f28e3 100644
--- a/src/TNL/Experimental/Multimaps/EllpackIndexMultimap_impl.h
+++ b/src/TNL/Experimental/Multimaps/EllpackIndexMultimap_impl.h
@@ -76,12 +76,12 @@ void
 EllpackIndexMultimap< Index, Device >::
 allocate( const ValuesAllocationVectorType& portsCount )
 {
-   Assert( portsCount.getSize() == this->keysRange,
+   TNL_ASSERT( portsCount.getSize() == this->keysRange,
               std::cerr << "portsCount.getSize() =  " << portsCount.getSize()
                    << "this->inputs = " << this->keysRange );
    this->valuesMaxCount = portsCount.max();
  
-   Assert( this->valuesMaxCount >= 0 && this->valuesMaxCount <= this->valuesRange,
+   TNL_ASSERT( this->valuesMaxCount >= 0 && this->valuesMaxCount <= this->valuesRange,
               std::cerr << "this->portsMaxCount = " << this->valuesMaxCount
                    << " this->outputs = " << this->valuesRange );
    this->values.setSize( this->keysRange * this->valuesMaxCount );
diff --git a/src/TNL/File.cpp b/src/TNL/File.cpp
index d6e16b17ac89c0d0cd5c9b3f262f47b7eb2ad28c..885173cd40a320f67d149f5b1be6193012059600 100644
--- a/src/TNL/File.cpp
+++ b/src/TNL/File.cpp
@@ -15,7 +15,7 @@ namespace TNL {
 int File :: verbose = 0;
 
 File :: File()
-: mode( tnlUndefinedMode ),
+: mode( IOMode::undefined ),
   file( NULL ),
   fileOK( false ),
   writtenElements( 0 ),
@@ -23,26 +23,37 @@ File :: File()
 {
 }
 
+File :: ~File()
+{
+   // destroying a file without closing is a memory leak
+   // (an open file descriptor is left behind, on Linux there is typically
+   // only a limited number of descriptors available to each process)
+   close();
+}
+
 bool File :: open( const String& fileName,
-                      const tnlIOMode mode )
+                   const IOMode mode )
 {
+   // close the existing file to avoid memory leaks
+   this->close();
+
    this->fileName = fileName;
    if( verbose )
    {
       std::cout << "Opening file " << fileName;
-      if( mode == tnlReadMode )
+      if( mode == IOMode::read )
          std::cout << " for reading... " << std::endl;
       else
          std::cout << " for writing ... " << std::endl;
    }
-   if( mode == tnlReadMode )
-      file = fopen( fileName. getString(), "r" );
-   if( mode == tnlWriteMode )
-      file = fopen( fileName. getString(), "w" );
+   if( mode == IOMode::read )
+      file = std::fopen( fileName.getString(), "rb" );
+   if( mode == IOMode::write )
+      file = std::fopen( fileName.getString(), "wb" );
    if( file ==  NULL )
    {
       std::cerr << "I am not able to open the file " << fileName << ". ";
-      perror( "" );
+      std::perror( "" );
       return false;
    }
    this->fileOK = true;
@@ -55,24 +66,25 @@ bool File :: close()
    if( verbose )
       std::cout << "Closing the file " << getFileName() << " ... " << std::endl;
 
-   if( fclose( file ) != 0 )
+   if( file && std::fclose( file ) != 0 )
    {
       std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl;
       return false;
    }
+   // reset all attributes
+   mode = IOMode::undefined;
+   file = NULL;
+   fileOK = false;
+   fileName = "";
    readElements = writtenElements = 0;
    return true;
-};
+}
 
 bool fileExists( const String& fileName )
 {
   std::fstream file;
-  file.open( fileName. getString(), std::ios::in );
-  bool result( true );
-  if( ! file )
-     result = false;
-  file.close();
-  return result;
-};
+  file.open( fileName.getString(), std::ios::in );
+  return ! file.fail();
+}
 
 } // namespace TNL
diff --git a/src/TNL/File.h b/src/TNL/File.h
index 9ea11d299a1d160eec562d156ab35d9c9112b8f4..78861f5690a86901b170e0056830fe59250faf6e 100644
--- a/src/TNL/File.h
+++ b/src/TNL/File.h
@@ -12,22 +12,22 @@
 
 #include <iostream>
 #include <fstream>
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_CUDA
-   #include <cuda_runtime.h>
-#endif
+#include <cstdio>
 
 #include <TNL/Assert.h>
 #include <TNL/String.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/MIC.h>
 
 namespace TNL {
 
-enum tnlIOMode { tnlUndefinedMode = 0,
-                 tnlReadMode = 1,
-                 tnlWriteMode = 2 };
+enum class IOMode
+{
+   undefined = 0,
+   read = 1,
+   write = 2
+};
 
 /* When we need to transfer data between the GPU and the CPU we use
  * 5 MB buffer. This size should ensure good performance -- see.
@@ -41,57 +41,43 @@ const size_t tnlFileGPUvsCPUTransferBufferSize = 5 * 2<<20;
  */
 class File
 {
-   tnlIOMode mode;
+   IOMode mode;
 
-   FILE* file;
+   std::FILE* file;
 
    bool fileOK;
 
    String fileName;
 
-   size_t writtenElements;
+   std::size_t writtenElements;
 
-   size_t readElements;
+   std::size_t readElements;
 
    public:
 
    File();
 
+   ~File();
+
    bool open( const String& fileName,
-              const tnlIOMode mode );
+              const IOMode mode );
 
 
-	const String& getFileName() const
+   const String& getFileName() const
    {
-	   return this->fileName;
+      return this->fileName;
    }
 
-	long int getReadElements() const
-	{
-	   return this->readElements;
-	}
-
-	long int getWrittenElements() const
-	{
-	   return this->writtenElements;
-	}
-
-	// TODO: this does not work for constant types
-#ifdef HAVE_NOT_CXX11
-	template< typename Type, typename Device, typename Index >
-	bool read( Type* buffer,
-	           const Index& elements );
-
-	template< typename Type, typename Device >
-	bool read( Type* buffer );
+   long int getReadElements() const
+   {
+      return this->readElements;
+   }
 
-	template< typename Type, typename Device, typename Index >
-	bool write( const Type* buffer,
-	            const Index elements );
+   long int getWrittenElements() const
+   {
+      return this->writtenElements;
+   }
 
-	template< typename Type, typename Device >
-	bool write( const Type* buffer );
-#else
    template< typename Type, typename Device = Devices::Host, typename Index = int >
    bool read( Type* buffer,
               const Index& elements );
@@ -106,12 +92,52 @@ class File
    template< typename Type, typename Device = Devices::Host >
    bool write( const Type* buffer );
 
-#endif
-
-	bool close();
-
-	static int verbose;
-
+   bool close();
+
+   static int verbose;
+
+protected:
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
+   bool read_impl( Type* buffer,
+                   const std::size_t& elements );
+
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
+             typename = void >
+   bool read_impl( Type* buffer,
+                   const std::size_t& elements );
+
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
+             typename = void,
+             typename = void >
+   bool read_impl( Type* buffer,
+                   const std::size_t& elements );
+
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
+   bool write_impl( const Type* buffer,
+                    const std::size_t& elements );
+
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
+             typename = void >
+   bool write_impl( const Type* buffer,
+                    const std::size_t& elements );
+
+   template< typename Type,
+             typename Device,
+             typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
+             typename = void,
+             typename = void >
+   bool write_impl( const Type* buffer,
+                    const std::size_t& elements );
 };
 
 bool fileExists( const String& fileName );
@@ -119,4 +145,3 @@ bool fileExists( const String& fileName );
 } // namespace TNL
 
 #include <TNL/File_impl.h>
-
diff --git a/src/TNL/File_impl.h b/src/TNL/File_impl.h
index 3342c4b5e168096742b51c789aad5bf91a08e036..932399045f9e2b9990a6272788bbcd8a6f685aea 100644
--- a/src/TNL/File_impl.h
+++ b/src/TNL/File_impl.h
@@ -8,33 +8,38 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#pragma once 
+#pragma once
+
+#include <type_traits>
+
+#include <TNL/File.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
+#include <TNL/Exceptions/MICSupportMissing.h>
 
 namespace TNL {
 
+
 template< typename Type, typename Device >
-bool File :: read( Type* buffer )
+bool File::read( Type* buffer )
 {
    return read< Type, Device, int >( buffer, 1 );
-};
+}
 
 template< typename Type, typename Device >
-bool File :: write( const Type* buffer )
+bool File::write( const Type* buffer )
 {
    return write< Type, Device, int >( buffer, 1 );
-};
-
+}
 
 template< typename Type, typename Device, typename Index >
-bool File :: read( Type* buffer,
-                   const Index& _elements )
+bool File::read( Type* buffer,
+                 const Index& _elements )
 {
-   Assert( _elements >= 0,
-           std::cerr << " elements = " << _elements << std::endl; );
+   TNL_ASSERT_GE( _elements, 0, "Number of elements to read must be non-negative." );
 
-   // convert _elements from Index to size_t, which is *unsigned* type
+   // convert _elements from Index to std::size_t, which is *unsigned* type
    // (expected by fread etc)
-   size_t elements = (size_t) _elements;
+   std::size_t elements = (std::size_t) _elements;
 
    if( ! elements )
       return true;
@@ -43,95 +48,141 @@ bool File :: read( Type* buffer,
       std::cerr << "File " << fileName << " was not properly opened. " << std::endl;
       return false;
    }
-   if( mode != tnlReadMode )
+   if( mode != IOMode::read )
    {
       std::cerr << "File " << fileName << " was not opened for reading. " << std::endl;
       return false;
    }
+
+   return read_impl< Type, Device >( buffer, elements );
+}
+
+// Host
+template< typename Type,
+          typename Device,
+          typename >
+bool File::read_impl( Type* buffer,
+                      const std::size_t& elements )
+{
    this->readElements = 0;
-   const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ),
-                                             elements );
-   void* host_buffer( 0 );
-   if( std::is_same< Device, Devices::Host >::value )
+   if( std::fread( buffer,
+                   sizeof( Type ),
+                   elements,
+                   file ) != elements )
    {
-      if( fread( buffer,
-             sizeof( Type ),
-             elements,
-             file ) != elements )
+      std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl;
+      std::perror( "Fread ended with the error code" );
+      return false;
+   }
+   this->readElements = elements;
+   return true;
+}
+
+// Cuda
+template< typename Type,
+          typename Device,
+          typename, typename >
+bool File::read_impl( Type* buffer,
+                      const std::size_t& elements )
+{
+#ifdef HAVE_CUDA
+   this->readElements = 0;
+   const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements );
+   using BaseType = typename std::remove_cv< Type >::type;
+   BaseType* host_buffer = new BaseType[ host_buffer_size ];
+
+   while( readElements < elements )
+   {
+      std::size_t transfer = std::min( elements - readElements, host_buffer_size );
+      std::size_t transfered = std::fread( host_buffer, sizeof( Type ), transfer, file );
+      if( transfered != transfer )
       {
          std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl;
-         perror( "Fread ended with the error code" );
+         std::cerr << transfered << " bytes were transfered. " << std::endl;
+         std::perror( "Fread ended with the error code" );
+         delete[] host_buffer;
          return false;
       }
-      this->readElements = elements;
-      return true;
+
+      cudaMemcpy( ( void* ) & ( buffer[ readElements ] ),
+                  host_buffer,
+                  transfer * sizeof( Type ),
+                  cudaMemcpyHostToDevice );
+      if( ! TNL_CHECK_CUDA_DEVICE )
+      {
+         std::cerr << "Transfer of data from the CUDA device to the file " << this->fileName
+              << " failed." << std::endl;
+         delete[] host_buffer;
+         return false;
+      }
+      this->readElements += transfer;
    }
-   if( std::is_same< Device, Devices::Cuda >::value )
+   delete[] host_buffer;
+   return true;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+// MIC
+template< typename Type,
+          typename Device,
+          typename, typename, typename >
+bool File::read_impl( Type* buffer,
+                      const std::size_t& elements )
+{
+#ifdef HAVE_MIC
+   this->readElements = 0;
+   const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements );
+   Type * host_buffer = (Type *)malloc( sizeof( Type ) * host_buffer_size );
+   readElements = 0;
+   if( ! host_buffer )
    {
-#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 )
+      std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
+                << this->getFileName() << "." << std::endl;
+      return false;
+   }
+
+   while( readElements < elements )
+   {
+      int transfer = std::min(  elements - readElements , host_buffer_size );
+      size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file );
+      if( transfered != transfer )
       {
-         std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
-              << this->getFileName() << "." << std::endl;
+         std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl;
+         std::cerr << transfered << " bytes were transfered. " << std::endl;
+         perror( "Fread ended with the error code" );
          return false;
-
       }
-
-      while( readElements < elements )
+      Devices::MICHider<Type> device_buff;
+      device_buff.pointer=buffer;
+      #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer))
       {
-         size_t transfer = std::min( elements - readElements, host_buffer_size );
-         size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file );
-         if( transfered != transfer )
-         {
-            std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl;
-            std::cerr << transfered << " bytes were transfered. " << std::endl;
-            perror( "Fread ended with the error code" );
-            return false;
-         }
-
-         cudaMemcpy( ( void* ) & ( buffer[ readElements ] ),
-                     host_buffer,
-                     transfer * sizeof( Type ),
-                     cudaMemcpyHostToDevice );
-         if( ! checkCudaDevice )
-         {
-            std::cerr << "Transfer of data from the CUDA device to the file " << this->fileName
-                 << " failed." << std::endl;
-            free( host_buffer );
-            return false;
-         }
-         readElements += transfer;
+         /*
+         for(int i=0;i<transfer;i++)
+              device_buff.pointer[readElements+i]=host_buffer[i];
+          */
+         memcpy(&(device_buff.pointer[readElements]),host_buffer, transfer*sizeof(Type) );
       }
-      free( host_buffer );
-      return true;
-#else
-      CudaSupportMissingMessage;;
-      return false;
-#endif
+
+      readElements += transfer;
    }
+   free( host_buffer );
    return true;
-};
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
 
 template< class Type, typename Device, typename Index >
-bool File :: write( const Type* buffer,
-                    const Index _elements )
+bool File::write( const Type* buffer,
+                  const Index _elements )
 {
-   Assert( _elements >= 0,
-           std::cerr << " elements = " << _elements << std::endl; );
+   TNL_ASSERT_GE( _elements, 0, "Number of elements to write must be non-negative." );
 
-   // convert _elements from Index to size_t, which is *unsigned* type
+   // convert _elements from Index to std::size_t, which is *unsigned* type
    // (expected by fread etc)
-   size_t elements = (size_t) _elements;
+   std::size_t elements = (std::size_t) _elements;
 
    if( ! elements )
       return true;
@@ -140,85 +191,134 @@ bool File :: write( const Type* buffer,
       std::cerr << "File " << fileName << " was not properly opened. " << std::endl;
       return false;
    }
-   if( mode != tnlWriteMode )
+   if( mode != IOMode::write )
    {
       std::cerr << "File " << fileName << " was not opened for writing. " << std::endl;
       return false;
    }
 
-   Type* buf = const_cast< Type* >( buffer );
-   void* host_buffer( 0 );
+   return write_impl< Type, Device >( buffer, elements );
+}
+
+// Host
+template< typename Type,
+          typename Device,
+          typename >
+bool File::write_impl( const Type* buffer,
+                       const std::size_t& elements )
+{
+   this->writtenElements = 0;
+   if( std::fwrite( buffer,
+                    sizeof( Type ),
+                    elements,
+                    this->file ) != elements )
+   {
+      std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl;
+      std::perror( "Fwrite ended with the error code" );
+      return false;
+   }
+   this->writtenElements = elements;
+   return true;
+}
+
+// Cuda
+template< typename Type,
+          typename Device,
+          typename, typename >
+bool File::write_impl( const Type* buffer,
+                       const std::size_t& elements )
+{
+#ifdef HAVE_CUDA
    this->writtenElements = 0;
-   const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ),
+   const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ),
                                              elements );
-   if( std::is_same< Device, Devices::Host >::value )
+   using BaseType = typename std::remove_cv< Type >::type;
+   BaseType* host_buffer = new BaseType[ host_buffer_size ];
+
+   while( this->writtenElements < elements )
    {
-      if( fwrite( buf,
-                  sizeof( Type ),
-                  elements,
-                  this->file ) != elements )
+      std::size_t transfer = std::min( elements - this->writtenElements, host_buffer_size );
+      cudaMemcpy( host_buffer,
+                  ( void* ) & ( buffer[ this->writtenElements ] ),
+                  transfer * sizeof( Type ),
+                  cudaMemcpyDeviceToHost );
+      if( ! TNL_CHECK_CUDA_DEVICE )
+      {
+         std::cerr << "Transfer of data from the file " << this->fileName
+              << " to the CUDA device failed." << std::endl;
+         delete[] host_buffer;
+         return false;
+      }
+      if( std::fwrite( host_buffer,
+                       sizeof( Type ),
+                       transfer,
+                       this->file ) != transfer )
       {
          std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl;
-         perror( "Fwrite ended with the error code" );
+         std::perror( "Fwrite ended with the error code" );
+         delete[] host_buffer;
          return false;
       }
-      this->writtenElements = elements;
-      return true;
+      this->writtenElements += transfer;
    }
-   if( std::is_same< Device, Devices::Cuda >::value )
+   delete[] host_buffer;
+   return true;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+// MIC
+template< typename Type,
+          typename Device,
+          typename, typename, typename >
+bool File::write_impl( const Type* buffer,
+                       const std::size_t& elements )
+{
+#ifdef HAVE_MIC
+   this->writtenElements = 0;
+   const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ),
+                                                  elements );
+   Type * host_buffer = (Type *)malloc( sizeof( Type ) * host_buffer_size );
+   if( ! host_buffer )
    {
-#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.
+      std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
+                << this->getFileName() << "." << std::endl;
+      return false;
+   }
+
+   while( this->writtenElements < elements )
+   {
+       std::size_t transfer = std::min( elements - this->writtenElements, host_buffer_size );
+
+      Devices::MICHider<const Type> device_buff;
+      device_buff.pointer=buffer;
+      #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer))
+      {
+         //THIS SHOULD WORK... BUT NOT WHY?
+         /*for(int i=0;i<transfer;i++)
+              host_buffer[i]=device_buff.pointer[writtenElements+i];
           */
-         host_buffer = malloc( sizeof( Type ) * host_buffer_size );
-         if( ! host_buffer )
-         {
-            std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
-                 << this->getFileName() << "." << std::endl;
-            return false;
-         }
-
-         while( this->writtenElements < elements )
-         {
-            size_t transfer = std::min( elements - this->writtenElements, host_buffer_size );
-            cudaMemcpy( host_buffer,
-                       ( void* ) & ( buffer[ this->writtenElements ] ),
-                       transfer * sizeof( Type ),
-                       cudaMemcpyDeviceToHost );
-            if( ! checkCudaDevice )
-            {
-               std::cerr << "Transfer of data from the file " << this->fileName
-                    << " to the CUDA device failed." << std::endl;
-               free( host_buffer );
-               return false;
-            }
-            if( fwrite( host_buffer,
-                        sizeof( Type ),
-                        transfer,
-                        this->file ) != transfer )
-            {
-               std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl;
-               perror( "Fwrite ended with the error code" );
-               return false;
-            }
-            this->writtenElements += transfer;
-         }
-         free( host_buffer );
-         return true;
-#else
-         CudaSupportMissingMessage;;
+
+         memcpy(host_buffer,&(device_buff.pointer[writtenElements]), transfer*sizeof(Type) );
+      }
+
+      if( fwrite( host_buffer,
+                  sizeof( Type ),
+                  transfer,
+                  this->file ) != transfer )
+      {
+         std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl;
+         perror( "Fwrite ended with the error code" );
          return false;
-#endif
+      }
+      this->writtenElements += transfer;
    }
+   free( host_buffer );
    return true;
-};
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
 
 } // namespace TNL
-
-
diff --git a/src/TNL/Functions/Analytic/Blob.h b/src/TNL/Functions/Analytic/Blob.h
index 56c6e22b7eab001f03b45137b23ba6f2582d4798..e12a27393c7077f71fe57137a6fce3a2abc00d0c 100644
--- a/src/TNL/Functions/Analytic/Blob.h
+++ b/src/TNL/Functions/Analytic/Blob.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump.h  -  description
+                          Blob.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -20,8 +20,8 @@ namespace Functions {
 namespace Analytic {
    
 template< typename Real,
-          int Dimensions >
-class BlobBase : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class BlobBase : public Domain< Dimension, SpaceDomain >
 {
    public:
 
@@ -35,7 +35,7 @@ class BlobBase : public Domain< Dimensions, SpaceDomain >
       RealType height;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class Blob
 {
@@ -46,29 +46,23 @@ class Blob< 1, Real > : public BlobBase< Real, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Blob();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
 };
 
@@ -77,29 +71,23 @@ class Blob< 2, Real > : public BlobBase< Real, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Blob();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
 
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -109,35 +97,29 @@ class Blob< 3, Real > : public BlobBase< Real, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Blob();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const Blob< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const Blob< Dimension, Real >& f )
 {
    str << "Level-set pseudo square function.";
    return str;
diff --git a/src/TNL/Functions/Analytic/Blob_impl.h b/src/TNL/Functions/Analytic/Blob_impl.h
index c6d969d38527cfab69858a39f3d2fac3b340287e..f615a10dd7826decd3ec2432e29e96a54371824e 100644
--- a/src/TNL/Functions/Analytic/Blob_impl.h
+++ b/src/TNL/Functions/Analytic/Blob_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump_impl.h  -  description
+                          Blob_impl.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -17,9 +17,9 @@ namespace Functions {
 namespace Analytic {
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 bool
-BlobBase< Real, Dimensions >::
+BlobBase< Real, Dimension >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -51,7 +51,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 1, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -66,7 +66,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -94,7 +94,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 2, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -110,7 +110,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -138,7 +138,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 3, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -153,7 +153,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Blob< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/CMakeLists.txt b/src/TNL/Functions/Analytic/CMakeLists.txt
old mode 100755
new mode 100644
index 01c91a1542b9b1cfdbb1bae7c2e37c4ce44fdb91..744345453d919ac82f2ef2a39186774f90c1b652
--- a/src/TNL/Functions/Analytic/CMakeLists.txt
+++ b/src/TNL/Functions/Analytic/CMakeLists.txt
@@ -7,13 +7,21 @@ SET( headers Blob.h
              ExpBump.h
              ExpBump_impl.h
 	     Flowerpot.h
-             Flowerpot_impl.h 
+             Flowerpot_impl.h
+             Paraboloid.h
+             Paraboloid_impl.h
+             ParaboloidSDF.h
+             ParaboloidSDF_impl.h
 	     PseudoSquare.h
              PseudoSquare_impl.h
              SinBumps.h
              SinBumps_impl.h
+             SinBumpsSDF.h
+             SinBumpsSDF_impl.h
              SinWave.h
              SinWave_impl.h
+             SinWaveSDF.h
+             SinWaveSDF_impl.h
 	     Twins.h
              Twins_impl.h 
    )
diff --git a/src/TNL/Functions/Analytic/Constant.h b/src/TNL/Functions/Analytic/Constant.h
index dc12be876f6adc50d423940d1c13c194adb26563..927d5a421320cd91eeaaa759add37126f3242c0e 100644
--- a/src/TNL/Functions/Analytic/Constant.h
+++ b/src/TNL/Functions/Analytic/Constant.h
@@ -25,8 +25,9 @@ class Constant : public Domain< dimensions, NonspaceDomain >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< dimensions, RealType > VertexType;
+      typedef Containers::StaticVector< dimensions, RealType > PointType;
  
+      __cuda_callable__
       Constant();
 
       static void configSetup( Config::ConfigDescription& config,
@@ -39,21 +40,15 @@ class Constant : public Domain< dimensions, NonspaceDomain >
 
       const RealType& getConstant() const;
 
-   #ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-   #else
-      template< int XDiffOrder,
+      template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-   #endif
       __cuda_callable__ inline
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
 
       __cuda_callable__ inline
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const
       {
          return constant;
diff --git a/src/TNL/Functions/Analytic/Constant_impl.h b/src/TNL/Functions/Analytic/Constant_impl.h
index 5754a7017a1699c4bba2f45e3d422e02db8815fa..bbd46853dc3cbe98448819876ffc8fc17940cc1a 100644
--- a/src/TNL/Functions/Analytic/Constant_impl.h
+++ b/src/TNL/Functions/Analytic/Constant_impl.h
@@ -14,46 +14,47 @@ namespace TNL {
 namespace Functions {
 namespace Analytic {   
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-Constant< Dimensions, Real >::
+__cuda_callable__
+Constant< Dimension, Real >::
 Constant()
 : constant( 0.0 )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 void
-Constant< Dimensions, Real >::
+Constant< Dimension, Real >::
 setConstant( const RealType& constant )
 {
    this->constant = constant;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 const Real&
-Constant< Dimensions, Real >::
+Constant< Dimension, Real >::
 getConstant() const
 {
    return this->constant;
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real >
 void
-Constant< FunctionDimensions, Real >::
+Constant< FunctionDimension, Real >::
 configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
    config.addEntry     < double >( prefix + "constant", "Value of the constant function.", 0.0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 bool
-Constant< Dimensions, Real >::
+Constant< Dimension, Real >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -61,14 +62,14 @@ setup( const Config::ParameterContainer& parameters,
    return true;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder >
 Real
-Constant< Dimensions, Real >::
-getPartialDerivative( const VertexType& v,
+Constant< Dimension, Real >::
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    if( XDiffOrder || YDiffOrder || ZDiffOrder )
diff --git a/src/TNL/Functions/Analytic/Cylinder.h b/src/TNL/Functions/Analytic/Cylinder.h
index bdfde9bd8d144bb187b333c638a653241be38c80..fb3f0542ceda6b3c1b334c300419549d5217bf2b 100644
--- a/src/TNL/Functions/Analytic/Cylinder.h
+++ b/src/TNL/Functions/Analytic/Cylinder.h
@@ -20,8 +20,8 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
-class CylinderBase : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class CylinderBase : public Domain< Dimension, SpaceDomain >
 {
    public:
 
@@ -39,7 +39,7 @@ class CylinderBase : public Domain< Dimensions, SpaceDomain >
       RealType diameter;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class Cylinder
 {
@@ -50,31 +50,24 @@ class Cylinder< 1, Real > : public CylinderBase< Real, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Cylinder();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
 
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -84,31 +77,24 @@ class Cylinder< 2, Real > : public CylinderBase< Real, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Cylinder();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -118,38 +104,31 @@ class Cylinder< 3, Real > : public CylinderBase< Real, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Cylinder();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const Cylinder< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const Cylinder< Dimension, Real >& f )
 {
    str << "Cylinder function.";
    return str;
diff --git a/src/TNL/Functions/Analytic/Cylinder_impl.h b/src/TNL/Functions/Analytic/Cylinder_impl.h
index 56a27935db2c7e3d198536babb64a4c1a956f4c4..b0698bca32056610195f5a9ab23c3e603455e1e5 100644
--- a/src/TNL/Functions/Analytic/Cylinder_impl.h
+++ b/src/TNL/Functions/Analytic/Cylinder_impl.h
@@ -17,9 +17,9 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 bool
-CylinderBase< Real, Dimensions >::
+CylinderBase< Real, Dimension >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -28,17 +28,17 @@ setup( const Config::ParameterContainer& parameters,
 }
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 void
-CylinderBase< Real, Dimensions >::
+CylinderBase< Real, Dimension >::
 setDiameter( const Real& sigma )
 {
    this->diameter = diameter;
 }
 
 template< typename Real,
-          int Dimensions >
-const Real& CylinderBase< Real, Dimensions >::getDiameter() const
+          int Dimension >
+const Real& CylinderBase< Real, Dimension >::getDiameter() const
 {
    return this->diameter;
 }
@@ -63,10 +63,10 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
-Cylinder< 1, Real >::getPartialDerivative( const Vertex& v,
+Cylinder< 1, Real >::getPartialDerivative( const Point& v,
                                                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -81,7 +81,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Cylinder< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -107,11 +107,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Cylinder< 2, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -127,7 +127,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Cylinder< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -154,11 +154,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Cylinder< 3, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -173,7 +173,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Cylinder< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/ExpBump.h b/src/TNL/Functions/Analytic/ExpBump.h
index 9b8e40a8220c8bf36de4fc0515b962183d3b1fa1..36b07c9a27d549532fb055c01c075cf5e30aa8a8 100644
--- a/src/TNL/Functions/Analytic/ExpBump.h
+++ b/src/TNL/Functions/Analytic/ExpBump.h
@@ -44,7 +44,7 @@ class ExpBumpBase : public Domain< dimensions, SpaceDomain >
       RealType amplitude, sigma;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class ExpBump
 {
@@ -56,27 +56,21 @@ class ExpBump< 1, Real > : public ExpBumpBase< 1, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 1, RealType > VertexType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
 
       static String getType();
 
       ExpBump();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
    __cuda_callable__
-   RealType getPartialDerivative( const VertexType& v,
+   RealType getPartialDerivative( const PointType& v,
                                   const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const RealType& time = 0.0 ) const;
 };
 
@@ -86,27 +80,21 @@ class ExpBump< 2, Real > : public ExpBumpBase< 2, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 2, RealType > VertexType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
 
       static String getType();
 
       ExpBump();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
    __cuda_callable__ inline
-   RealType getPartialDerivative( const VertexType& v,
+   RealType getPartialDerivative( const PointType& v,
                                   const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const Real& time = 0.0 ) const;
 };
 
@@ -116,35 +104,29 @@ class ExpBump< 3, Real > : public ExpBumpBase< 3, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 3, RealType > VertexType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
 
  
       static String getType();
 
       ExpBump();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
    __cuda_callable__
-   RealType getPartialDerivative( const VertexType& v,
+   RealType getPartialDerivative( const PointType& v,
                                   const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const ExpBump< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const ExpBump< Dimension, Real >& f )
 {
    str << "ExpBump. function: amplitude = " << f.getAmplitude() << " sigma = " << f.getSigma();
    return str;
diff --git a/src/TNL/Functions/Analytic/ExpBump_impl.h b/src/TNL/Functions/Analytic/ExpBump_impl.h
index 10e0c85528112934db051f51cf8d684e5d14707f..54ecbe2a66fb011e827c1c876aa385ad4b4eee57 100644
--- a/src/TNL/Functions/Analytic/ExpBump_impl.h
+++ b/src/TNL/Functions/Analytic/ExpBump_impl.h
@@ -82,7 +82,7 @@ template< typename Real >
 __cuda_callable__
 Real
 ExpBump< 1, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    using namespace std;
@@ -102,7 +102,7 @@ template< typename Real >
 __cuda_callable__
 Real
 ExpBump< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -132,7 +132,7 @@ template< typename Real >
 __cuda_callable__ inline
 Real
 ExpBump< 2, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -158,7 +158,7 @@ template< typename Real >
 __cuda_callable__
 Real
 ExpBump< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -187,7 +187,7 @@ template< typename Real >
 __cuda_callable__
 Real
 ExpBump< 3, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -220,7 +220,7 @@ template< typename Real >
 __cuda_callable__
 Real
 ExpBump< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/Flowerpot.h b/src/TNL/Functions/Analytic/Flowerpot.h
index c8df009b7e42c7b955775c2b4486a423529d0252..5a42c5f94249aa69c320959a9713f13f88beec56 100644
--- a/src/TNL/Functions/Analytic/Flowerpot.h
+++ b/src/TNL/Functions/Analytic/Flowerpot.h
@@ -20,8 +20,8 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
-class FlowerpotBase : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class FlowerpotBase : public Domain< Dimension, SpaceDomain >
 {
    public:
 
@@ -39,7 +39,7 @@ class FlowerpotBase : public Domain< Dimensions, SpaceDomain >
       RealType diameter;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class Flowerpot
 {
@@ -50,31 +50,24 @@ class Flowerpot< 1, Real > : public FlowerpotBase< Real, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Flowerpot();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -84,31 +77,24 @@ class Flowerpot< 2, Real > : public FlowerpotBase< Real, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Flowerpot();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -118,38 +104,31 @@ class Flowerpot< 3, Real > : public FlowerpotBase< Real, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Flowerpot();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const Flowerpot< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const Flowerpot< Dimension, Real >& f )
 {
    str << "Flowerpot function.";
    return str;
diff --git a/src/TNL/Functions/Analytic/Flowerpot_impl.h b/src/TNL/Functions/Analytic/Flowerpot_impl.h
index a3da8b4d2ae38d0972861cf49e77081240c1781c..455b4682b29780bdf526b45adf9b228c7c225073 100644
--- a/src/TNL/Functions/Analytic/Flowerpot_impl.h
+++ b/src/TNL/Functions/Analytic/Flowerpot_impl.h
@@ -17,9 +17,9 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 bool
-FlowerpotBase< Real, Dimensions >::
+FlowerpotBase< Real, Dimension >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -28,15 +28,15 @@ setup( const Config::ParameterContainer& parameters,
 }
 
 template< typename Real,
-          int Dimensions >
-void FlowerpotBase< Real, Dimensions >::setDiameter( const Real& sigma )
+          int Dimension >
+void FlowerpotBase< Real, Dimension >::setDiameter( const Real& sigma )
 {
    this->diameter = diameter;
 }
 
 template< typename Real,
-          int Dimensions >
-const Real& FlowerpotBase< Real, Dimensions >::getDiameter() const
+          int Dimension >
+const Real& FlowerpotBase< Real, Dimension >::getDiameter() const
 {
    return this->diameter;
 }
@@ -61,10 +61,10 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
-Flowerpot< 1, Real >::getPartialDerivative( const Vertex& v,
+Flowerpot< 1, Real >::getPartialDerivative( const Point& v,
                                                        const Real& time ) const
 {
    const RealType& x = v.x();
@@ -79,7 +79,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Flowerpot< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -105,11 +105,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Flowerpot< 2, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -125,7 +125,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Flowerpot< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -152,11 +152,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Flowerpot< 3, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -171,7 +171,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Flowerpot< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/Paraboloid.h b/src/TNL/Functions/Analytic/Paraboloid.h
new file mode 100644
index 0000000000000000000000000000000000000000..7bbdcca53402994574d45e07526e5af0839a1ec7
--- /dev/null
+++ b/src/TNL/Functions/Analytic/Paraboloid.h
@@ -0,0 +1,150 @@
+/***************************************************************************
+                          Paraboloid.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Functions/Domain.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< int dimensions,
+          typename Real = double >
+class ParaboloidBase : public Functions::Domain< dimensions, SpaceDomain >
+{
+   public:
+
+   ParaboloidBase();
+
+   bool setup( const Config::ParameterContainer& parameters,
+              const String& prefix = "" );
+
+   void setXCenter( const Real& waveLength );
+
+   Real getXCenter() const;
+
+   void setYCenter( const Real& waveLength );
+
+   Real getYCenter() const;
+
+   void setZCenter( const Real& waveLength );
+
+   Real getZCenter() const;
+
+   void setCoefficient( const Real& coefficient );
+
+   Real getCoefficient() const;
+
+   void setOffset( const Real& offset );
+
+   Real getOffset() const;
+
+   protected:
+
+   Real xCenter, yCenter, zCenter, coefficient, radius;
+};
+
+template< int Dimensions, typename Real >
+class Paraboloid
+{
+};
+
+template< typename Real >
+class Paraboloid< 1, Real > : public ParaboloidBase< 1, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const
+      {
+         return this->getPartialDerivative< 0, 0, 0 >( v, time );
+      }
+
+};
+
+template< typename Real >
+class Paraboloid< 2, Real > : public ParaboloidBase< 2, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const
+      {
+         return this->getPartialDerivative< 0, 0, 0 >( v, time );
+      }
+
+};
+
+template< typename Real >
+class Paraboloid< 3, Real > : public ParaboloidBase< 3, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
+
+
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const
+      {
+         return this->getPartialDerivative< 0, 0, 0 >( v, time );
+      }
+
+};
+
+template< int Dimensions,
+          typename Real >
+std::ostream& operator << ( std::ostream& str, const Paraboloid< Dimensions, Real >& f )
+{
+   str << "SDF Paraboloid function: amplitude = " << f.getCoefficient()
+       << " offset = " << f.getOffset();
+   return str;
+}
+        
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
+
+#include <TNL/Functions/Analytic/Paraboloid_impl.h>
+
diff --git a/src/TNL/Functions/Analytic/ParaboloidSDF.h b/src/TNL/Functions/Analytic/ParaboloidSDF.h
new file mode 100644
index 0000000000000000000000000000000000000000..60a8cedfd754c1ff350c659475b24bd5d5dedaff
--- /dev/null
+++ b/src/TNL/Functions/Analytic/ParaboloidSDF.h
@@ -0,0 +1,142 @@
+/***************************************************************************
+                          ParaboloidSDF.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once 
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Functions/Domain.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< int dimensions,
+          typename Real = double >
+class ParaboloidSDFBase : public Functions::Domain< dimensions, SpaceDomain >
+{
+   public:
+
+   ParaboloidSDFBase();
+
+   bool setup( const Config::ParameterContainer& parameters,
+              const String& prefix = "" );
+
+   void setXCenter( const Real& waveLength );
+
+   Real getXCenter() const;
+
+   void setYCenter( const Real& waveLength );
+
+   Real getYCenter() const;
+
+   void setZCenter( const Real& waveLength );
+
+   Real getZCenter() const;
+
+   void setCoefficient( const Real& coefficient );
+
+   Real getCoefficient() const;
+
+   void setOffset( const Real& offset );
+
+   Real getOffset() const;
+
+   protected:
+
+   Real xCenter, yCenter, zCenter, coefficient, radius;
+};
+
+template< int Dimensions, typename Real >
+class ParaboloidSDF
+{
+};
+
+template< typename Real >
+class ParaboloidSDF< 1, Real > : public ParaboloidSDFBase< 1, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class ParaboloidSDF< 2, Real > : public ParaboloidSDFBase< 2, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class ParaboloidSDF< 3, Real > : public ParaboloidSDFBase< 3, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
+
+
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< int Dimensions,
+          typename Real >
+std::ostream& operator << ( std::ostream& str, const ParaboloidSDF< Dimensions, Real >& f )
+{
+   str << "SDF Paraboloid SDF function: amplitude = " << f.getCoefficient()
+       << " offset = " << f.getOffset();
+   return str;
+}
+         
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
+
+
+#include <TNL/Functions/Analytic/ParaboloidSDF_impl.h>
+
diff --git a/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h b/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7a79b515756a17bef3addd2e707246f408c6375
--- /dev/null
+++ b/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+                          ParaboloidSDFSDF_impl.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once 
+
+#include <TNL/Functions/Analytic/ParaboloidSDF.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< int dimensions, typename Real >
+ParaboloidSDFBase< dimensions, Real >::ParaboloidSDFBase()
+: xCenter( 0 ), yCenter( 0 ), zCenter( 0 ),
+  coefficient( 1 ), radius ( 0 )
+{
+}
+
+template< int dimensions, typename Real >
+bool ParaboloidSDFBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters,
+        								 const String& prefix)
+{
+   this->xCenter = parameters.getParameter< double >( "x-center" );
+   this->yCenter = parameters.getParameter< double >( "y-center" );
+   this->zCenter = parameters.getParameter< double >( "z-center" );
+   this->coefficient = parameters.getParameter< double >( "coefficient" );
+   this->radius = parameters.getParameter< double >( "radius" );
+
+   return true;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidSDFBase< dimensions, Real >::setXCenter( const Real& xCenter )
+{
+   this->xCenter = xCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidSDFBase< dimensions, Real >::getXCenter() const
+{
+   return this->xCenter;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidSDFBase< dimensions, Real >::setYCenter( const Real& yCenter )
+{
+   this->yCenter = yCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidSDFBase< dimensions, Real >::getYCenter() const
+{
+   return this->yCenter;
+}
+template< int dimensions, typename Real >
+void ParaboloidSDFBase< dimensions, Real >::setZCenter( const Real& zCenter )
+{
+   this->zCenter = zCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidSDFBase< dimensions, Real >::getZCenter() const
+{
+   return this->zCenter;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidSDFBase< dimensions, Real >::setCoefficient( const Real& amplitude )
+{
+   this->coefficient = coefficient;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidSDFBase< dimensions, Real >::getCoefficient() const
+{
+   return this->coefficient;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidSDFBase< dimensions, Real >::setOffset( const Real& offset )
+{
+   this->radius = offset;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidSDFBase< dimensions, Real >::getOffset() const
+{
+   return this->radius;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+ParaboloidSDF< 1, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return ::sqrt( ( x - this -> xCenter ) * ( x - this -> xCenter ) ) - this->radius;
+   if( XDiffOrder == 1 )
+      return 1.0;
+   return 0.0;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+ParaboloidSDF< 2, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   const Real& y = v.y();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+   {
+      return ::sqrt ( ( x - this -> xCenter ) * ( x - this -> xCenter )
+    		  	  + ( y - this -> yCenter ) * ( y - this -> yCenter ) ) - this->radius;
+   }
+   return 0.0;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+ParaboloidSDF< 3, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   const Real& y = v.y();
+   const Real& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+   {
+      return ::sqrt( ( x - this -> xCenter ) * ( x - this -> xCenter )
+    		  	 + ( y - this -> yCenter ) * ( y - this -> yCenter )
+    		  	 + ( z - this -> zCenter ) * ( z - this -> zCenter ) ) - this->radius;
+   }
+   return 0.0;
+}
+         
+      } //namespace Analytic
+   } // namepsace Functions
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/Paraboloid_impl.h b/src/TNL/Functions/Analytic/Paraboloid_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..866388a2f4d7430de5eae0565194a07ff65d283d
--- /dev/null
+++ b/src/TNL/Functions/Analytic/Paraboloid_impl.h
@@ -0,0 +1,185 @@
+/***************************************************************************
+                          Paraboloid_impl.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once 
+
+#include <TNL/Functions/Analytic/Paraboloid.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< int dimensions, typename Real >
+ParaboloidBase< dimensions, Real >::ParaboloidBase()
+: xCenter( 0 ), yCenter( 0 ), zCenter( 0 ),
+  coefficient( 1 ), radius ( 0 )
+{
+}
+
+template< int dimensions, typename Real >
+bool ParaboloidBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters,
+        								 const String& prefix)
+{
+   this->xCenter = parameters.getParameter< double >( "x-center" );
+   this->yCenter = parameters.getParameter< double >( "y-center" );
+   this->zCenter = parameters.getParameter< double >( "z-center" );
+   this->coefficient = parameters.getParameter< double >( "coefficient" );
+   this->radius = parameters.getParameter< double >( "radius" );
+
+   return true;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidBase< dimensions, Real >::setXCenter( const Real& xCenter )
+{
+   this->xCenter = xCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidBase< dimensions, Real >::getXCenter() const
+{
+   return this->xCenter;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidBase< dimensions, Real >::setYCenter( const Real& yCenter )
+{
+   this->yCenter = yCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidBase< dimensions, Real >::getYCenter() const
+{
+   return this->yCenter;
+}
+template< int dimensions, typename Real >
+void ParaboloidBase< dimensions, Real >::setZCenter( const Real& zCenter )
+{
+   this->zCenter = zCenter;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidBase< dimensions, Real >::getZCenter() const
+{
+   return this->zCenter;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidBase< dimensions, Real >::setCoefficient( const Real& amplitude )
+{
+   this->coefficient = coefficient;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidBase< dimensions, Real >::getCoefficient() const
+{
+   return this->coefficient;
+}
+
+template< int dimensions, typename Real >
+void ParaboloidBase< dimensions, Real >::setOffset( const Real& offset )
+{
+   this->radius = offset;
+}
+
+template< int dimensions, typename Real >
+Real ParaboloidBase< dimensions, Real >::getOffset() const
+{
+   return this->radius;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+Paraboloid< 1, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter ) - this->radius*this->radius );
+   if( XDiffOrder == 1 )
+      return 2.0 * this->coefficient * ( x - this -> xCenter );
+   return 0.0;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+Paraboloid< 2, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   const Real& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+   {
+      return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter )
+    		  	  	  	         + ( y - this -> yCenter ) * ( y - this -> yCenter ) - this->radius*this->radius );
+   }
+   if( XDiffOrder == 1 && YDiffOrder == 0)
+	   return 2.0 * this->coefficient * ( x - this -> xCenter );
+   if( YDiffOrder == 1 && XDiffOrder == 0)
+	   return 2.0 * this->coefficient * ( y - this -> yCenter );
+   if( XDiffOrder == 2 && YDiffOrder == 0)
+	   return 2.0 * this->coefficient;
+   if( YDiffOrder == 2 && XDiffOrder == 0)
+	   return 2.0 * this->coefficient;
+   return 0.0;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+Paraboloid< 3, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const Real& x = v.x();
+   const Real& y = v.y();
+   const Real& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+   {
+      return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter )
+    		  	  	  	         + ( y - this -> yCenter ) * ( y - this -> yCenter )
+    		  	  	  	         + ( z - this -> zCenter ) * ( z - this -> zCenter ) - this->radius*this->radius );
+   }
+   if( XDiffOrder == 1 && YDiffOrder == 0 && ZDiffOrder == 0)
+	   return 2.0 * this->coefficient * ( x - this -> xCenter );
+   if( YDiffOrder == 1 && XDiffOrder == 0 && ZDiffOrder == 0)
+	   return 2.0 * this->coefficient * ( y - this -> yCenter );
+   if( ZDiffOrder == 1 && XDiffOrder == 0 && YDiffOrder == 0)
+	   return 2.0 * this->coefficient * ( z - this -> zCenter );
+   if( XDiffOrder == 2 && YDiffOrder == 0 && ZDiffOrder == 0)
+	   return 2.0 * this->coefficient;
+   if( YDiffOrder == 2 && XDiffOrder == 0 && ZDiffOrder == 0)
+	   return 2.0 * this->coefficient;
+   if( ZDiffOrder == 2 && XDiffOrder == 0 && YDiffOrder == 0)
+	   return 2.0 * this->coefficient;
+   return 0.0;
+}
+         
+      } // namespace Analytic
+   } // namedspace Functions
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/PseudoSquare.h b/src/TNL/Functions/Analytic/PseudoSquare.h
index 26d3086f23b1fa855acec067dc0b72a5ba878e1e..ea4a5ae84e7e306560e67c74f40075cd3cc5a883 100644
--- a/src/TNL/Functions/Analytic/PseudoSquare.h
+++ b/src/TNL/Functions/Analytic/PseudoSquare.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump.h  -  description
+                          PseudoSquare.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -20,8 +20,8 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
-class PseudoSquareBase : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class PseudoSquareBase : public Domain< Dimension, SpaceDomain >
 {
    public:
 
@@ -35,7 +35,7 @@ class PseudoSquareBase : public Domain< Dimensions, SpaceDomain >
       RealType height;
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class PseudoSquare
 {
@@ -46,29 +46,23 @@ class PseudoSquare< 1, Real > : public PseudoSquareBase< Real, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       PseudoSquare();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
 };
 
@@ -77,29 +71,23 @@ class PseudoSquare< 2, Real > : public PseudoSquareBase< Real, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       PseudoSquare();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
 };
 
@@ -108,36 +96,30 @@ class PseudoSquare< 3, Real > : public PseudoSquareBase< Real, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       PseudoSquare();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const PseudoSquare< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const PseudoSquare< Dimension, Real >& f )
 {
    str << "Level-set pseudo square function.";
    return str;
diff --git a/src/TNL/Functions/Analytic/PseudoSquare_impl.h b/src/TNL/Functions/Analytic/PseudoSquare_impl.h
index 378e11ac11c720b573a46d922b4d66cdb63ee66b..5da33707a43307bf4b343384e924f15b5a1518b6 100644
--- a/src/TNL/Functions/Analytic/PseudoSquare_impl.h
+++ b/src/TNL/Functions/Analytic/PseudoSquare_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump_impl.h  -  description
+                          PseudoSquare_impl.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -17,9 +17,9 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 bool
-PseudoSquareBase< Real, Dimensions >::
+PseudoSquareBase< Real, Dimension >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -52,7 +52,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 1, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -67,7 +67,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -95,7 +95,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 2, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -111,7 +111,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -139,7 +139,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 3, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -154,7 +154,7 @@ template< typename Real >
 __cuda_callable__
 Real
 PseudoSquare< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/SDFSchemeTest.h b/src/TNL/Functions/Analytic/SDFSchemeTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8433cacaafcdb22165c7b4e7157ffdcb1372878
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SDFSchemeTest.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+                          SDFSchemeTest.h  -  description
+                             -------------------
+    begin                : Nov 19, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlSDFSinWaveFunction.h>
+#include <functions/tnlSDFSinWaveFunctionSDF.h>
+#include <functions/tnlSDFSinBumps.h>
+#include <functions/tnlSDFSinBumpsSDF.h>
+#include <functions/tnlExpBumpFunction.h>
+#include <functions/tnlSDFParaboloid.h>
+#include <functions/tnlSDFParaboloidSDF.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< typename function, typename Real = double >
+class SDFSchemeTestBase
+{
+   public:
+
+   SDFSchemeTestBase();
+
+   bool setup( const Config::ParameterContainer& parameters,
+           const String& prefix = "" );
+
+
+   	function f;
+};
+
+template< typename function, int Dimensions, typename Real >
+class SDFSchemeTest
+{
+
+};
+
+template< typename function, int Dimensions, typename Real >
+class SDFSchemeTest< function, 1, Real > : public SDFSchemeTestBase< function, Real >
+{
+   public:
+
+
+   enum { Dimensions = 1 };
+   typedef Point PointType;
+   typedef typename PointType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const PointType& v,
+           const Real& time = 0.0 ) const;
+
+
+
+};
+
+template< typename function, int Dimensions, typename Real >
+class SDFSchemeTest< function, 2, Real > : public SDFSchemeTestBase< function, Real >
+{
+   public:
+
+
+   enum { Dimensions = 2 };
+   typedef Point PointType;
+   typedef typename PointType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const PointType& v,
+           const Real& time = 0.0 ) const;
+
+
+};
+
+template< typename function, int Dimensions, typename Real >
+class SDFSchemeTest< function, 3, Real > : public SDFSchemeTestBase< function,  Real >
+{
+   public:
+
+
+   enum { Dimensions = 3 };
+   typedef Point PointType;
+   typedef typename PointType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const PointType& v,
+           const Real& time = 0.0 ) const;
+
+};
+
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
+
+#include <functions/SDFSchemeTest_impl.h>
diff --git a/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h b/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2344965698016f6fd7e2019974f34bb5338f9ad6
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+                          SDFSchemeTest_impl.h  -  description
+                             -------------------
+    begin                : Nov 19, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <functions/SDFSchemeTest.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< typename function, typename Real >
+SDFSchemeTestBase< function, Real >::SDFSchemeTestBase()
+{
+}
+
+template< typename function, typename Real >
+bool SDFSchemeTestBase< function, Real >::v( const Config::ParameterContainer& parameters,
+        const String& prefix = "" )
+{
+	f.init(parameters);
+
+   return true;
+}
+
+
+
+template< typename function, int Dimensions, typename Real >
+   template< int XDiffOrder, int YDiffOrder, int ZDiffOrder >
+Real SDFSchemeTest< function, 1, Real >::getValue( const Point& v,
+              const Real& time = 0.0 ) const
+{
+   if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 )
+      return 0.0;
+
+   return sign( this->f.getValue<0,0,0>(v))*
+		   	   ( 1-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v)) );
+}
+
+
+template< typename function, int Dimensions, typename Real >
+   template< int XDiffOrder, int YDiffOrder, int ZDiffOrder >
+Real SDFSchemeTest< function, 2, Real >::getValue( const Point& v,
+              const Real& time = 0.0 ) const
+{
+	   if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 )
+	      return 0.0;
+
+	   return sign( this->f.getValue<0,0,0>(v))*
+			   ( 1-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v) +
+					    this->f.getValue<0,1,0>(v)*this->f.getValue<0,1,0>(v)) );
+}
+
+template< typename function, int Dimensions, typename Real >
+   template< int XDiffOrder, int YDiffOrder, int ZDiffOrder >
+Real SDFSchemeTest< function, 3, Real >::getValue( const Point& v,
+              const Real& time = 0.0 ) const
+{
+	   if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 )
+	      return 0.0;
+
+	   return sign( this->f.getValue<0,0,0>(v))*
+			   ( 1.0-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v) +
+					      this->f.getValue<0,1,0>(v)*this->f.getValue<0,1,0>(v) +
+					      this->f.getValue<0,0,1>(v)*this->f.getValue<0,0,1>(v)) );
+}
+
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
+
diff --git a/src/TNL/Functions/Analytic/SinBumps.h b/src/TNL/Functions/Analytic/SinBumps.h
index d3cc0434582e8b0c6df273f3063f382d1bef3ebb..19b176cc8d48578db7ad3c314b89b30eb66ec760 100644
--- a/src/TNL/Functions/Analytic/SinBumps.h
+++ b/src/TNL/Functions/Analytic/SinBumps.h
@@ -8,7 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#pragma once
+/****
+ * Tomas Sobotik
+ */
+
+#pragma once 
 
 #include <TNL/Config/ParameterContainer.h>
 #include <TNL/Containers/StaticVector.h>
@@ -18,35 +22,39 @@ namespace TNL {
 namespace Functions {
 namespace Analytic {   
 
-template< typename Vertex >
-class SinBumpsBase : public Domain< Vertex::size, SpaceDomain >
+template< typename Point >
+class SinBumpsBase : public Domain< Point::size, SpaceDomain >
 {
    public:
  
-      typedef Vertex VertexType;
-      typedef typename Vertex::RealType RealType;
-      enum { Dimensions = VertexType::size };
+      typedef Point PointType;
+      typedef typename Point::RealType RealType;
+      enum { Dimension = PointType::size };
 
-      void setWaveLength( const VertexType& waveLength );
+      void setWaveLength( const PointType& waveLength );
 
-      const VertexType& getWaveLength() const;
+      const PointType& getWaveLength() const;
 
       void setAmplitude( const RealType& amplitude );
 
       const RealType& getAmplitude() const;
 
-      void setPhase( const VertexType& phase );
+      void setPhase( const PointType& phase );
+
+      const PointType& getPhase() const;
 
-      const VertexType& getPhase() const;
+      void setWavesNumber( const PointType& wavesNumber );
+
+      const PointType& getWavesNumber() const;
 
    protected:
 
       RealType amplitude;
 
-      VertexType waveLength, phase;
+      PointType waveLength, wavesNumber, phase;
 };
 
-template< int Dimensions, typename Real >
+template< int Dimension, typename Real >
 class SinBumps
 {
 };
@@ -57,29 +65,22 @@ class SinBumps< 1, Real  > : public SinBumpsBase< Containers::StaticVector< 1, R
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 1, RealType > VertexType;
-
+      typedef Containers::StaticVector< 1, RealType > PointType;
 
       SinBumps();
 
       bool setup( const Config::ParameterContainer& parameters,
                   const String& prefix = "" );
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const Real& time = 0.0 ) const;
  
 };
@@ -90,7 +91,7 @@ class SinBumps< 2, Real > : public SinBumpsBase< Containers::StaticVector< 2, Re
    public:
 
       typedef Real RealType;
-      typedef Containers::StaticVector< 2, RealType > VertexType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
  
 
       SinBumps();
@@ -98,21 +99,15 @@ class SinBumps< 2, Real > : public SinBumpsBase< Containers::StaticVector< 2, Re
       bool setup( const Config::ParameterContainer& parameters,
                  const String& prefix = "" );
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const Real& time = 0.0 ) const;
  
 };
@@ -123,35 +118,29 @@ class SinBumps< 3, Real > : public SinBumpsBase< Containers::StaticVector< 3, Re
    public:
 
       typedef Real RealType;
-      typedef Containers::StaticVector< 3, RealType > VertexType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
 
       SinBumps();
 
       bool setup( const Config::ParameterContainer& parameters,
                   const String& prefix = "" );
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                          const Real& time = 0.0 ) const;
  
    __cuda_callable__
-   RealType operator()( const VertexType& v,
+   RealType operator()( const PointType& v,
                         const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const SinBumps< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const SinBumps< Dimension, Real >& f )
 {
    str << "Sin Bumps. function: amplitude = " << f.getAmplitude()
        << " wavelength = " << f.getWaveLength()
@@ -163,4 +152,4 @@ std::ostream& operator << ( std::ostream& str, const SinBumps< Dimensions, Real
 } // namespace Functions
 } // namespace TNL
 
-#include <TNL/Functions/Analytic/SinBumps_impl.h>
\ No newline at end of file
+#include <TNL/Functions/Analytic/SinBumps_impl.h>
diff --git a/src/TNL/Functions/Analytic/SinBumpsSDF.h b/src/TNL/Functions/Analytic/SinBumpsSDF.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2e242eb4a3bea1fbd784d0923f7f95d4dc0d532
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinBumpsSDF.h
@@ -0,0 +1,154 @@
+/***************************************************************************
+                          SinBumpsSDF.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once 
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Functions/Domain.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+
+template< typename Point >
+class SinBumpsSDFBase : public Domain< Point::size, SpaceDomain >
+{
+   public:
+
+      typedef Point PointType;
+      typedef typename Point::RealType RealType;
+      enum { Dimensions = PointType::size };
+
+      void setWaveLength( const PointType& waveLength );
+
+      const PointType& getWaveLength() const;
+
+      void setAmplitude( const RealType& amplitude );
+
+      const RealType& getAmplitude() const;
+
+      void setPhase( const PointType& phase );
+
+      const PointType& getPhase() const;
+
+      void setWavesNumber( const PointType& wavesNumber );
+
+      const PointType& getWavesNumber() const;
+
+   protected:
+
+      RealType amplitude;
+
+      PointType waveLength, phase, wavesNumber;
+};
+
+template< int Dimensions, typename Real >
+class SinBumpsSDF
+{
+};
+
+template< typename Real >
+class SinBumpsSDF< 1, Real  > : public SinBumpsSDFBase< Containers::StaticVector< 1, Real > >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
+
+
+      SinBumpsSDF();
+
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" );
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const PointType& v,
+                        const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinBumpsSDF< 2, Real > : public SinBumpsSDFBase< Containers::StaticVector< 2, Real > >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
+
+
+      SinBumpsSDF();
+
+      bool setup( const Config::ParameterContainer& parameters,
+                 const String& prefix = "" );
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const PointType& v,
+                        const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinBumpsSDF< 3, Real > : public SinBumpsSDFBase< Containers::StaticVector< 3, Real > >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
+
+      SinBumpsSDF();
+
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" );
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                         const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const PointType& v,
+                        const Real& time = 0.0 ) const;
+
+};
+
+template< int Dimensions,
+          typename Real >
+std::ostream& operator << ( std::ostream& str, const SinBumpsSDF< Dimensions, Real >& f )
+{
+   str << "SDF Sin Bumps SDF. function: amplitude = " << f.getAmplitude()
+       << " wavelength = " << f.getWaveLength()
+       << " phase = " << f.getPhase();
+   return str;
+}
+
+
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
+
+#include <TNL/Functions/Analytic/SinBumpsSDF_impl.h>
diff --git a/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4852a50358a615e02cd518a6ac0e71c4cc909657
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h
@@ -0,0 +1,242 @@
+/***************************************************************************
+                          SinBumpsSDFSDF_impl.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once 
+
+#include <TNL/Functions/Analytic/SinBumpsSDF.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< typename Point >
+void SinBumpsSDFBase< Point >::setWaveLength( const Point& waveLength )
+{
+   this->waveLength = waveLength;
+}
+
+template< typename Point >
+const Point& SinBumpsSDFBase< Point >::getWaveLength() const
+{
+   return this->waveLength;
+}
+
+template< typename Point >
+void SinBumpsSDFBase< Point >::setAmplitude( const typename Point::RealType& amplitude )
+{
+   this->amplitude = amplitude;
+}
+
+template< typename Point >
+const typename Point::RealType& SinBumpsSDFBase< Point >::getAmplitude() const
+{
+   return this->amplitude;
+}
+
+template< typename Point >
+void SinBumpsSDFBase< Point >::setPhase( const Point& phase )
+{
+   this->phase = phase;
+}
+
+template< typename Point >
+const Point& SinBumpsSDFBase< Point >::getPhase() const
+{
+   return this->phase;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+SinBumpsSDF< 1, Real >::SinBumpsSDF()
+{
+}
+
+template< typename Real >
+bool SinBumpsSDF< 1, Real >::setup( const Config::ParameterContainer& parameters,
+        const String& prefix)
+{
+   this->amplitude = parameters.getParameter< double >( prefix+"amplitude" );
+   this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" );
+   while(this->waveLength.x() > 2.0*M_PI)
+	   this->waveLength.x() -= 2.0*M_PI;
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
+   this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" );
+   return true;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+SinBumpsSDF< 1, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / ( 2.0*M_PI );
+   if( this->wavesNumber.x() != 0.0 && xp > this->wavesNumber.x() * this->waveLength.x() )
+      return 0.0;
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return sign( xp - round( (2.0 * xp ) / this->waveLength.x() ) * this->waveLength.x() / 2.0 )
+          * ( xp- round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0)
+          * sign( ::sin(this-> phase.x() + 2.0 * M_PI * x / this->waveLength.x()));
+   if( XDiffOrder == 1 )
+      return 1.0;
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+SinBumpsSDF< 2, Real >::SinBumpsSDF()
+{
+}
+
+template< typename Real >
+bool SinBumpsSDF< 2, Real >::setup( const Config::ParameterContainer& parameters,
+        const String& prefix )
+{
+   this->amplitude = parameters.getParameter< double >( prefix+"amplitude" );
+   this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" );
+   this->waveLength.y() = parameters.getParameter< double >( prefix+"wave-length-y" );
+   while(this->waveLength.x() > 2.0*M_PI)
+	   this->waveLength.x() -= 2.0*M_PI;
+   while(this->waveLength.y() > 2.0*M_PI)
+	   this->waveLength.y() -= 2.0*M_PI;
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
+   this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) );
+   this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" );
+   this->phase.y() = parameters.getParameter< double >( prefix+"phase-y" );
+   return true;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+SinBumpsSDF< 2, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+	   const RealType& x = v.x();
+	   const RealType& y = v.y();
+	   RealType xp = ::sqrt(x*x) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+	   RealType yp = ::sqrt(y*y) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+	   if( ( xp > this->wavesNumber.x()*this->waveLength.x() && this->wavesNumber.x() != 0.0 )  ||
+			 ( yp > this->wavesNumber.y()*this->waveLength.y() && this->wavesNumber.y() != 0.0 ) )
+		   return 0.0;
+	   const RealType sx = sign(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0)
+	  		  		    *(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0);
+	   const RealType sy = sign(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0)
+	  		  		    *(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0);
+	   RealType sxy;
+	   if(sx < sy)
+		   sxy = sx;
+	   else
+		   sxy = sy;
+	   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+	   {
+		      return sxy * sign( ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() )
+		      	  	  	       * ::sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) );
+	   }
+	   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+SinBumpsSDF< 3, Real >::SinBumpsSDF()
+{
+}
+
+template< typename Real >
+bool SinBumpsSDF< 3, Real >::setup( const Config::ParameterContainer& parameters,
+        const String& prefix )
+{
+   this->amplitude = parameters.getParameter< double >( prefix+"amplitude" );
+   this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" );
+   this->waveLength.y() = parameters.getParameter< double >( prefix+"wave-length-y" );
+   this->waveLength.z() = parameters.getParameter< double >( prefix+"wave-length-z" );
+   while(this->waveLength.x() > 2.0*M_PI)
+	   this->waveLength.x() -= 2.0*M_PI;
+   while(this->waveLength.y() > 2.0*M_PI)
+	   this->waveLength.y() -= 2.0*M_PI;
+   while(this->waveLength.z() > 2.0*M_PI)
+	   this->waveLength.z() -= 2.0*M_PI;
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
+   this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) );
+   this->wavesNumber.z() = ceil( parameters.getParameter< double >( prefix+"waves-number-z" ) );
+   this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" );
+   this->phase.y() = parameters.getParameter< double >( prefix+"phase-y" );
+   this->phase.z() = parameters.getParameter< double >(prefix+"phase-z" );
+   return true;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+SinBumpsSDF< 3, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+	   const RealType& x = v.x();
+	   const RealType& y = v.y();
+	   const RealType& z = v.z();
+	   RealType xp = ::sqrt(x*x) + sign(x)*(this->phase.x())*(this->waveLength.x())/(2.0*M_PI);
+	   RealType yp = ::sqrt(y*y) + sign(y)*(this->phase.y())*(this->waveLength.y())/(2.0*M_PI);
+	   RealType zp = ::sqrt(z*z) + sign(z)*(this->phase.z())*(this->waveLength.z())/(2.0*M_PI);
+	   if ( ( xp > this->wavesNumber.x()*this->waveLength.x() && this->wavesNumber.x() != 0.0 ) ||
+			(yp > this->wavesNumber.y()*this->waveLength.y() && this->wavesNumber.y() != 0.0 ) ||
+			(::sqrt(z*z) > this->wavesNumber.z()*this->waveLength.z() && this->wavesNumber.z() != 0.0 ) )
+		   return 0.0;
+	   const RealType sx = sign(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0)
+	  		  		    *(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0);
+	   const RealType sy = sign(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0)
+	  		  		    *(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0);
+	   const RealType sz = sign(zp - round((2.0 * zp)/this->waveLength.z())* this->waveLength.z()/2.0)
+	  		  		    *(zp - round((2.0 * zp)/this->waveLength.z())* this->waveLength.z()/2.0);
+	   RealType sxyz;
+	   if(sx <= sy && sx <= sz)
+		   sxyz = sx;
+	   else if ( sy <= sx && sy <= sz)
+		   sxyz = sy;
+	   else
+		   sxyz = sz;
+	   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+	   {
+	      return sxyz * sign( ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() )
+	      	  	     	  	* ::sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() )
+	      	  	  	  	  	* ::sin( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() ) );
+	   }
+	   return 0.0;
+}
+
+      } // namespace Analytic
+   } // namespace Fucntions
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/SinBumps_impl.h b/src/TNL/Functions/Analytic/SinBumps_impl.h
index 8ae3eeb6abdce64ee0db3df89c5e59ada351f58b..44ea88c3c57d9512d8854f58520e892037eea127 100644
--- a/src/TNL/Functions/Analytic/SinBumps_impl.h
+++ b/src/TNL/Functions/Analytic/SinBumps_impl.h
@@ -8,6 +8,9 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/****
+ * Tomas Sobotik
+ */
 #pragma once
 
 #include <TNL/Functions/Analytic/SinBumps.h>
@@ -16,46 +19,57 @@ namespace TNL {
 namespace Functions {
 namespace Analytic {   
 
-template< typename Vertex >
-void SinBumpsBase< Vertex >::setWaveLength( const Vertex& waveLength )
+template< typename Point >
+void SinBumpsBase< Point >::setWaveLength( const Point& waveLength )
 {
    this->waveLength = waveLength;
 }
 
-template< typename Vertex >
-const Vertex& SinBumpsBase< Vertex >::getWaveLength() const
+template< typename Point >
+const Point& SinBumpsBase< Point >::getWaveLength() const
 {
    return this->waveLength;
 }
 
-template< typename Vertex >
-void SinBumpsBase< Vertex >::setAmplitude( const typename Vertex::RealType& amplitude )
+template< typename Point >
+void SinBumpsBase< Point >::setAmplitude( const typename Point::RealType& amplitude )
 {
    this->amplitude = amplitude;
 }
 
-template< typename Vertex >
-const typename Vertex::RealType& SinBumpsBase< Vertex >::getAmplitude() const
+template< typename Point >
+const typename Point::RealType& SinBumpsBase< Point >::getAmplitude() const
 {
    return this->amplitude;
 }
 
-template< typename Vertex >
-void SinBumpsBase< Vertex >::setPhase( const Vertex& phase )
+template< typename Point >
+void SinBumpsBase< Point >::setPhase( const Point& phase )
 {
    this->phase = phase;
 }
 
-template< typename Vertex >
-const Vertex& SinBumpsBase< Vertex >::getPhase() const
+template< typename Point >
+const Point& SinBumpsBase< Point >::getPhase() const
 {
    return this->phase;
 }
 
+template< typename Point >
+void SinBumpsBase< Point >::setWavesNumber( const Point& wavesNumber )
+{
+   this->wavesNumber = wavesNumber;
+}
+
+template< typename Point >
+const Point& SinBumpsBase< Point >::getWavesNumber() const
+{
+   return this->wavesNumber;
+}
+
 /***
  * 1D
  */
-
 template< typename Real >
 SinBumps< 1, Real >::SinBumps()
 {
@@ -68,6 +82,7 @@ bool SinBumps< 1, Real >::setup( const Config::ParameterContainer& parameters,
    this->amplitude = parameters.getParameter< double >( prefix + "amplitude" );
    this->waveLength.x() = parameters.getParameter< double >( prefix + "wave-length-x" );
    this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" );
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
    return true;
 }
 
@@ -79,12 +94,17 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 1, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
-   const RealType& x = v.x();
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
       return 0.0;
+   
+   const RealType& x = v.x();
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   if( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() )
+      return 0.0;
+  
    if( XDiffOrder == 0 )
       return this->amplitude * ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
    if( XDiffOrder == 1 )
@@ -98,7 +118,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -108,7 +128,6 @@ operator()( const VertexType& v,
 /****
  * 2D
  */
-
 template< typename Real >
 SinBumps< 2, Real >::SinBumps()
 {
@@ -123,10 +142,11 @@ bool SinBumps< 2, Real >::setup( const Config::ParameterContainer& parameters,
    this->waveLength.y() = parameters.getParameter< double >( prefix + "wave-length-y" );
    this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" );
    this->phase.y() = parameters.getParameter< double >( prefix + "phase-y" );
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
+   this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) );
    return true;
 }
 
-
 template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
@@ -134,13 +154,21 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 2, Real>::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
+   if( ZDiffOrder != 0 )
+      return 0.0;
+
    const RealType& x = v.x();
    const RealType& y = v.y();
-   if( ZDiffOrder != 0 )
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = abs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+   //std::cerr << "this->wavesNumber.x() = " << this->wavesNumber.x() << "fabs( x ) = " << fabs( x ) << " 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() = " << 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() << std::endl;
+   if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) ||
+       ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) )
       return 0.0;
+   
    if( XDiffOrder == 0 && YDiffOrder == 0 )
       return this->amplitude *
              ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) *
@@ -162,7 +190,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -171,7 +199,6 @@ operator()( const VertexType& v,
 /****
  * 3D
  */
-
 template< typename Real >
 SinBumps< 3, Real >::SinBumps()
 {
@@ -188,10 +215,12 @@ bool SinBumps< 3, Real >::setup( const Config::ParameterContainer& parameters,
    this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" );
    this->phase.y() = parameters.getParameter< double >( prefix + "phase-y" );
    this->phase.z() = parameters.getParameter< double >( prefix + "phase-z" );
+   this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) );
+   this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) );
+   this->wavesNumber.z() = ceil( parameters.getParameter< double >( prefix+"waves-number-z" ) );
    return true;
 }
 
-
 template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
@@ -199,12 +228,22 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 3, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
    const RealType& z = v.z();
+   
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = abs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+   const RealType zp = abs( z ) + sign( z ) * this->phase.z() * this->waveLength.z() / (2.0*M_PI);
+
+   if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) ||
+       ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) ||
+       ( this->wavesNumber.z() != 0.0 && zp > this->waveLength.z() * this->wavesNumber.z() ) )
+      return 0.0;
+   
    if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0)
       return this->amplitude *
              ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) *
@@ -235,7 +274,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinBumps< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/SinWave.h b/src/TNL/Functions/Analytic/SinWave.h
index 98c8cdddc6e8f9d0a0433fca653ade91d5d85665..635125818381d383f9db36f313498887f8f18ac3 100644
--- a/src/TNL/Functions/Analytic/SinWave.h
+++ b/src/TNL/Functions/Analytic/SinWave.h
@@ -8,6 +8,9 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/****
+ * Tomas Sobotik
+ */
 #pragma once
 
 #include <TNL/Config/ParameterContainer.h>
@@ -24,29 +27,35 @@ class SinWaveBase : public Domain< dimensions, SpaceDomain >
 {
    public:
  
-   SinWaveBase();
+      SinWaveBase();
 
-   bool setup( const Config::ParameterContainer& parameters,
-              const String& prefix = "" );
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" );
 
-   void setWaveLength( const Real& waveLength );
+      void setWaveLength( const Real& waveLength );
+      
+      Real getWaveLength() const;
 
-   Real getWaveLength() const;
+      void setAmplitude( const Real& amplitude );
 
-   void setAmplitude( const Real& amplitude );
+      Real getAmplitude() const;
 
-   Real getAmplitude() const;
+      void setPhase( const Real& phase );
 
-   void setPhase( const Real& phase );
+      Real getPhase() const;
 
-   Real getPhase() const;
+      void setWavesNumber( const Real& wavesNumber );
+
+      Real getWavesNumber() const;
 
    protected:
+      
+      bool isInsideWaves( const Real& distance ) const;
 
-   Real waveLength, amplitude, phase, wavesNumber;
+      Real waveLength, amplitude, phase, wavesNumber;
 };
 
-template< int Dimensions, typename Real >
+template< int Dimension, typename Real >
 class SinWave
 {
 };
@@ -57,23 +66,17 @@ class SinWave< 1, Real > : public SinWaveBase< 1, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 1, RealType > VertexType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
 
 };
@@ -84,23 +87,17 @@ class SinWave< 2, Real > : public SinWaveBase< 2, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 2, RealType > VertexType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
  
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -111,36 +108,31 @@ class SinWave< 3, Real > : public SinWaveBase< 3, Real >
    public:
  
       typedef Real RealType;
-      typedef Containers::StaticVector< 3, RealType > VertexType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
 
 
  
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
-#endif
       __cuda_callable__
-      RealType getPartialDerivative( const VertexType& v,
+      RealType getPartialDerivative( const PointType& v,
                          const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const SinWave< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const SinWave< Dimension, Real >& f )
 {
    str << "Sin Wave. function: amplitude = " << f.getAmplitude()
        << " wavelength = " << f.getWaveLength()
-       << " phase = " << f.getPhase();
+       << " phase = " << f.getPhase()
+       << " waves number = " << f.getWavesNumber();
    return str;
 }
 
diff --git a/src/TNL/Functions/Analytic/SinWaveSDF.h b/src/TNL/Functions/Analytic/SinWaveSDF.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4db3f3a5832749e2da34d9e516c75d07c595196
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinWaveSDF.h
@@ -0,0 +1,141 @@
+/***************************************************************************
+                          SinWaveSDF.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Functions/Domain.h>
+
+namespace TNL {
+   namespace Functions {
+      namespace Analytic {
+
+template< int dimensions,
+          typename Real = double >
+class SinWaveSDFBase : public Functions::Domain< dimensions, SpaceDomain >
+{
+   public:
+
+      SinWaveSDFBase();
+
+      bool setup( const Config::ParameterContainer& parameters,
+                 const String& prefix = "" );
+
+      void setWaveLength( const Real& waveLength );
+
+      Real getWaveLength() const;
+
+      void setAmplitude( const Real& amplitude );
+
+      Real getAmplitude() const;
+
+      void setPhase( const Real& phase );
+
+      Real getPhase() const;
+
+      void setWavesNumber( const Real& wavesNumber );
+
+      Real getWavesNumber() const;
+
+   protected:
+
+      __cuda_callable__
+      Real sinWaveFunctionSDF( const Real& r ) const;
+      
+      Real waveLength, amplitude, phase, wavesNumber;
+};
+
+template< int Dimensions, typename Real >
+class SinWaveSDF
+{
+};
+
+template< typename Real >
+class SinWaveSDF< 1, Real > : public SinWaveSDFBase< 1, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 1, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinWaveSDF< 2, Real > : public SinWaveSDFBase< 2, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinWaveSDF< 3, Real > : public SinWaveSDFBase< 3, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
+
+
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< int Dimensions,
+          typename Real >
+std::ostream& operator << ( std::ostream& str, const SinWaveSDF< Dimensions, Real >& f )
+{
+   str << "SDF Sin Wave SDF. function: amplitude = " << f.getAmplitude()
+       << " wavelength = " << f.getWaveLength()
+       << " phase = " << f.getPhase()
+       << " # of waves = " << f.getWavesNumber();
+   return str;
+}
+        
+      } // namespace Analytic
+   } // namespace Functions 
+} // namespace TNL
+
+#include <TNL/Functions/Analytic/SinWaveSDF_impl.h>
diff --git a/src/TNL/Functions/Analytic/SinWaveSDF_impl.h b/src/TNL/Functions/Analytic/SinWaveSDF_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d104ca32210896e9103dbd4205670da4202c1940
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinWaveSDF_impl.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+                          tnlSDFSinWaveFunctionSDFSDF_impl.h  -  description
+                             -------------------
+    begin                : Oct 13, 2014
+    copyright            : (C) 2014 by Tomas Sobotik
+
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Analytic/SinWaveSDF.h>
+
+namespace TNL {
+namespace Functions {
+namespace Analytic {
+
+template< int dimensions, typename Real >
+SinWaveSDFBase< dimensions, Real >::SinWaveSDFBase()
+: waveLength( 1.0 ),
+  amplitude( 1.0 ),
+  phase( 0 ),
+  wavesNumber( 0 )
+{
+}
+
+template< int dimensions, typename Real >
+bool SinWaveSDFBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters,
+                                           const String& prefix )
+{
+   this->waveLength = parameters.getParameter< double >( prefix + "wave-length" );
+   this->amplitude = parameters.getParameter< double >( prefix + "amplitude" );
+   this->phase = parameters.getParameter< double >( prefix + "phase" );
+   while(this->phase >2.0*M_PI)
+      this->phase -= 2.0*M_PI;
+   this->wavesNumber = ceil( parameters.getParameter< double >( prefix + "waves-number" ) );
+   return true;
+}
+
+template< int dimensions, typename Real >
+void SinWaveSDFBase< dimensions, Real >::setWaveLength( const Real& waveLength )
+{
+   this->waveLength = waveLength;
+}
+
+template< int dimensions, typename Real >
+Real SinWaveSDFBase< dimensions, Real >::getWaveLength() const
+{
+   return this->waveLength;
+}
+
+template< int dimensions, typename Real >
+void SinWaveSDFBase< dimensions, Real >::setAmplitude( const Real& amplitude )
+{
+   this->amplitude = amplitude;
+}
+
+template< int dimensions, typename Real >
+Real SinWaveSDFBase< dimensions, Real >::getAmplitude() const
+{
+   return this->amplitude;
+}
+
+template< int dimensions, typename Real >
+void SinWaveSDFBase< dimensions, Real >::setPhase( const Real& phase )
+{
+   this->phase = phase;
+}
+
+template< int dimensions, typename Real >
+Real SinWaveSDFBase< dimensions, Real >::getPhase() const
+{
+   return this->phase;
+}
+
+template< int dimensions, typename Real >
+void SinWaveSDFBase< dimensions, Real >::setWavesNumber( const Real& wavesNumber )
+{
+   this->wavesNumber = wavesNumber;
+}
+
+template< int dimensions, typename Real >
+Real SinWaveSDFBase< dimensions, Real >::getWavesNumber() const
+{
+   return this->wavesNumber;
+}
+
+template< int dimensions, typename Real >
+__cuda_callable__
+Real SinWaveSDFBase< dimensions, Real >::sinWaveFunctionSDF( const Real& r ) const
+{
+   if( this->wavesNumber == 0.0 || r < this->wavesNumber * this->waveLength )
+      return sign( r - round( 2.0 * r / this->waveLength ) * this->waveLength / 2.0 )
+             * ( r - round( 2.0 * r / this->waveLength ) * this->waveLength / 2.0 )
+             * sign( ::sin( 2.0 * M_PI * r / this->waveLength ) );
+   else
+      return r - this->wavesNumber * this->waveLength;   
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+SinWaveSDF< 1, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   const RealType& x = v.x();
+   const RealType distance = ::sqrt( x * x ) + this->phase * this->waveLength / (2.0*M_PI);
+   if( XDiffOrder == 0 )
+      return this->sinWaveFunctionSDF( distance );
+   TNL_ASSERT_TRUE( false, "TODO: implement this" );
+   return 0.0;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+SinWaveSDF< 2, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   if( ZDiffOrder != 0 )
+      return 0.0;
+
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType distance  = ::sqrt( x * x + y * y ) + this->phase * this->waveLength / (2.0*M_PI);
+   if( XDiffOrder == 0 && YDiffOrder == 0)
+      return this->sinWaveFunctionSDF( distance );
+   TNL_ASSERT_TRUE( false, "TODO: implement this" );
+   return 0.0;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+SinWaveSDF< 3, Real >::
+getPartialDerivative( const PointType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   const RealType distance  = ::sqrt( x * x +  y * y + z * z ) +  this->phase * this->waveLength / (2.0*M_PI);
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return this->sinWaveFunctionSDF( distance );
+   TNL_ASSERT_TRUE( false, "TODO: implement this" );
+   return 0.0;
+}
+
+} // namespace Analytic
+} // namespace Functions
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/SinWave_impl.h b/src/TNL/Functions/Analytic/SinWave_impl.h
index 56d3bd251203bde26d330daf7d06160551f4d94a..eea5f461561830037c96f1ac8ab327915a19fa33 100644
--- a/src/TNL/Functions/Analytic/SinWave_impl.h
+++ b/src/TNL/Functions/Analytic/SinWave_impl.h
@@ -81,7 +81,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 1, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -109,7 +109,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -124,7 +124,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 2, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -153,7 +153,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -167,7 +167,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 3, Real >::
-getPartialDerivative( const VertexType& v,
+getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -205,7 +205,7 @@ template< typename Real >
 __cuda_callable__
 Real
 SinWave< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/Twins.h b/src/TNL/Functions/Analytic/Twins.h
index ebdb507ac79e84681396715254ff4d4e30ff1b9e..c882ec4eb133c326195151b9d6db07098bec3735 100644
--- a/src/TNL/Functions/Analytic/Twins.h
+++ b/src/TNL/Functions/Analytic/Twins.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump.h  -  description
+                          Twins.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -20,8 +20,8 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
-class TwinsBase : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class TwinsBase : public Domain< Dimension, SpaceDomain >
 {
    public:
 
@@ -31,7 +31,7 @@ class TwinsBase : public Domain< Dimensions, SpaceDomain >
                  const String& prefix = "" );
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
 class Twins
 {
@@ -42,31 +42,24 @@ class Twins< 1, Real > : public TwinsBase< Real, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Twins();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -76,31 +69,24 @@ class Twins< 2, Real > : public TwinsBase< Real, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Twins();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
@@ -110,38 +96,31 @@ class Twins< 3, Real > : public TwinsBase< Real, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
       typedef Real RealType;
-      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
       static String getType();
 
       Twins();
 
-#ifdef HAVE_NOT_CXX11
-      template< int XDiffOrder,
-                int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
-#else
       template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0,
-                typename Vertex = VertexType >
-#endif
+                typename Point = PointType >
       __cuda_callable__
-      RealType getPartialDerivative( const Vertex& v,
+      RealType getPartialDerivative( const Point& v,
                                      const Real& time = 0.0 ) const;
  
       __cuda_callable__
-      RealType operator()( const VertexType& v,
+      RealType operator()( const PointType& v,
                            const Real& time = 0.0 ) const;
  
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-std::ostream& operator << ( std::ostream& str, const Twins< Dimensions, Real >& f )
+std::ostream& operator << ( std::ostream& str, const Twins< Dimension, Real >& f )
 {
    str << "Twins function.";
    return str;
diff --git a/src/TNL/Functions/Analytic/Twins_impl.h b/src/TNL/Functions/Analytic/Twins_impl.h
index 222f9a452adf289bcc9282c75cf2014ecc23c289..9e1cd81c185748cce2f038e0c55f154157056751 100644
--- a/src/TNL/Functions/Analytic/Twins_impl.h
+++ b/src/TNL/Functions/Analytic/Twins_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ExpBump_impl.h  -  description
+                          Twins_impl.h  -  description
                              -------------------
     begin                : Dec 5, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -17,9 +17,9 @@ namespace Functions {
 namespace Analytic {   
 
 template< typename Real,
-          int Dimensions >
+          int Dimension >
 bool
-TwinsBase< Real, Dimensions >::
+TwinsBase< Real, Dimension >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -47,10 +47,10 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
-Twins< 1, Real >::getPartialDerivative( const Vertex& v,
+Twins< 1, Real >::getPartialDerivative( const Point& v,
                                                    const Real& time ) const
 {
    const RealType& x = v.x();
@@ -65,7 +65,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Twins< 1, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -91,11 +91,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Twins< 2, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -111,7 +111,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Twins< 2, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
@@ -137,11 +137,11 @@ template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
              int ZDiffOrder,
-             typename Vertex >
+             typename Point >
 __cuda_callable__
 Real
 Twins< 3, Real >::
-getPartialDerivative( const Vertex& v,
+getPartialDerivative( const Point& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
@@ -156,7 +156,7 @@ template< typename Real >
 __cuda_callable__
 Real
 Twins< 3, Real >::
-operator()( const VertexType& v,
+operator()( const PointType& v,
             const Real& time ) const
 {
    return this->template getPartialDerivative< 0, 0, 0 >( v, time );
diff --git a/src/TNL/Functions/Analytic/VectorNorm.h b/src/TNL/Functions/Analytic/VectorNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..b54513705980249db0037044b00dabeca045bce6
--- /dev/null
+++ b/src/TNL/Functions/Analytic/VectorNorm.h
@@ -0,0 +1,293 @@
+/***************************************************************************
+                          VectorNorm.h  -  description
+                             -------------------
+    begin                : Feb 12, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Math.h>
+#include <TNL/Assert.h>
+
+namespace TNL {
+namespace Functions {
+namespace Analytic {   
+
+template< int Dimensions_,
+          typename Real >
+class VectorNormBase : public Domain< Dimensions_, SpaceDomain >
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions_, RealType > PointType;
+ 
+      VectorNormBase()
+         : center( 0.0 ),
+           anisotropy( 1.0 ),
+           power( 2.0 ),
+           radius( 0.0 ),
+           multiplicator( 1.0 ),
+           maxNorm( false ){};
+           
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "center-0", "x-coordinate of the coordinates origin for the vector norm.", 0.0 );
+         config.addEntry< double >( prefix + "center-1", "y-coordinate of the coordinates origin for the vector norm.", 0.0 );
+         config.addEntry< double >( prefix + "center-2", "z-coordinate of the coordinates origin for the vector norm.", 0.0 );
+         config.addEntry< double >( prefix + "anisotropy-0", "x-coordinate of the linear anisotropy of the vector norm.", 1.0 );
+         config.addEntry< double >( prefix + "anisotropy-1", "y-coordinate of the linear anisotropy of the vector norm.", 1.0 );
+         config.addEntry< double >( prefix + "anisotropy-2", "z-coordinate of the linear anisotropy of the vector norm.", 1.0 );
+         config.addEntry< double >( prefix + "power", "The p coefficient of the L-p vector norm", 2.0 );
+         config.addEntry< double >( prefix + "radius", "Radius of the zero-th level-set.", 0.0 );
+         config.addEntry< double >( prefix + "multiplicator", "Outer multiplicator of the norm - -1.0 turns the function graph upside/down.", 1.0 );
+         config.addEntry< bool >( prefix + "max-norm", "Turn to 'true' to get maximum norm.", false );
+      }
+ 
+      bool setup( const Config::ParameterContainer& parameters,
+                 const String& prefix = "" )
+      {
+         this->power = parameters.template getParameter< double >( prefix + "power" );
+         this->maxNorm = parameters.template getParameter< bool >( prefix + "max-norm" );
+         this->radius = parameters.template getParameter< double >( prefix + "radius" );
+         this->multiplicator = parameters.template getParameter< double >( prefix + "multiplicator" );
+         return( this->center.setup( parameters, prefix + "center-") &&
+                 this->anisotropy.setup( parameters, prefix + "anisotropy-" ) );
+      };
+
+      void setCenter( const PointType& center )
+      {
+         this->center = center;
+      };
+
+      const RealType& getCenter() const
+      {
+         return this->center;
+      }
+      
+      void setAnisotropy( const PointType& anisotropy )
+      {
+         this->anisotropy = anisotropy;
+      };
+
+      const RealType& getAnisotropy() const
+      {
+         return this->anisotropy;
+      }
+      
+      void setPower( const RealType& power )
+      {
+         this->power = power;
+      }
+      
+      const RealType& getPower() const
+      {
+         return this->power;
+      }
+      
+      void setRadius( const RealType& radius )
+      {
+         this->radius = radius;
+      }
+      
+      const RealType& getRadius() const
+      {
+         return this->radius;
+      }
+      
+      void setMultiplicator( const RealType& multiplicator )
+      {
+         this->multiplicator = multiplicator;
+      }
+      
+      const RealType& getMultiplicator() const
+      {
+         return this->multiplicator;
+      }
+      
+      void setMaxNorm( bool maxNorm )
+      {
+         this->maxNorm = maxNorm;
+      }
+      
+      const RealType& getMaxNorm() const
+      {
+         return this->maxNorm;
+      }
+      
+   protected:
+
+      PointType center, anisotropy;
+      
+      RealType power, radius, multiplicator;
+      
+      bool maxNorm;
+};
+
+template< int Dimensions,
+          typename Real >
+class VectorNorm
+{
+};
+
+template< typename Real >
+class VectorNorm< 1, Real > : public VectorNormBase< 1, Real >
+{
+   public:
+ 
+      typedef VectorNormBase< 1, Real > BaseType;      
+      using typename BaseType::RealType;
+      using typename BaseType::PointType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const
+      {
+         const RealType& x = v.x() - this->center.x();
+         if( YDiffOrder != 0 || ZDiffOrder != 0 )
+            return 0.0;
+         if( XDiffOrder == 0 )
+         {
+            return this->multiplicator * ( TNL::abs( x ) * this->anisotropy.x() - this->radius );
+         }
+         if( XDiffOrder == 1 )
+         {
+            return this->multiplicator * TNL::sign( x ) * this->anisotropy.x();
+         }
+         return 0.0;
+      }
+      
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const RealType& time = 0.0 ) const
+      {
+         return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+      }   
+};
+
+template< typename Real >
+class VectorNorm< 2, Real > : public VectorNormBase< 2, Real >
+{
+   public:
+      
+      typedef VectorNormBase< 2, Real > BaseType;      
+      using typename BaseType::RealType;
+      using typename BaseType::PointType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__ inline
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const
+      {
+         const RealType& x = v.x() - this->center.x();
+         const RealType& y = v.y() - this->center.y();
+         if( ZDiffOrder != 0 )
+            return 0.0;
+         if( XDiffOrder == 0 && YDiffOrder == 0 )
+         {
+            if( this->maxNorm )
+               return ( TNL::max( TNL::abs( x ) * this->anisotropy.x(), 
+                                  TNL::abs( y ) * this->anisotropy.y() ) - this->radius ) * this->multiplicator;
+            if( this->power == 1.0 )
+               return ( ( TNL::abs( x ) * this->anisotropy.x() + 
+                          TNL::abs( y ) * this->anisotropy.y() ) - this->radius ) * this->multiplicator;
+            if( this->power == 2.0 )
+               return ( std::sqrt( x * x  * this->anisotropy.x() + 
+                                   y * y  * this->anisotropy.y() ) - this->radius ) * this->multiplicator;
+            return ( std::pow( std::pow( TNL::abs( x ), this->power ) * this->anisotropy.x() + 
+                               std::pow( TNL::abs( y ), this->power ) * this->anisotropy.y(), 1.0 / this-> power ) - this->radius ) * this->multiplicator;
+         }
+         TNL_ASSERT_TRUE( false, "Not implemented yet." );
+         return 0.0;
+      }
+ 
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const
+      {
+         return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+      }
+};
+
+template< typename Real >
+class VectorNorm< 3, Real > : public VectorNormBase< 3, Real >
+{
+   public:
+ 
+      typedef VectorNormBase< 3, Real > BaseType;      
+      using typename BaseType::RealType;
+      using typename BaseType::PointType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const PointType& v,
+                                     const Real& time = 0.0 ) const
+      {
+         const RealType& x = v.x() - this->center.x();
+         const RealType& y = v.y() - this->center.y();
+         const RealType& z = v.z() - this->center.z();
+         if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+         {
+            if( this->maxNorm )
+               return ( TNL::max( TNL::max( TNL::abs( x ) * this->anisotropy.x(), 
+                                            TNL::abs( y ) * this->anisotropy.y() ),
+                                  TNL::abs( z ) * this->anisotropy.z() ) - this->radius ) * this->multiplicator;
+            if( this->power == 1.0 )
+               return ( ( TNL::abs( x ) * this->anisotropy.x() + 
+                          TNL::abs( y ) * this->anisotropy.y() +
+                          TNL::abs( z ) * this->anisotropy.z() ) - this->radius ) * this->multiplicator;
+            if( this->power == 2.0 )
+               return ( std::sqrt( x * x  * this->anisotropy.x() + 
+                                   y * y  * this->anisotropy.y() +
+                                   z * z  * this->anisotropy.z() ) - this->radius ) * this->multiplicator ;
+            return ( std::pow( std::pow( TNL::abs( x ), this->power ) * this->anisotropy.x() + 
+                               std::pow( TNL::abs( y ), this->power ) * this->anisotropy.y() +
+                               std::pow( TNL::abs( z ), this->power ) * this->anisotropy.z(), 1.0 / this-> power ) - this->radius ) * this->multiplicator;
+         }
+         TNL_ASSERT_TRUE( false, "Not implemented yet." );
+         return 0.0;
+      }
+      
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const Real& time = 0.0 ) const
+      {
+         return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+      } 
+};
+
+template< int Dimensions,
+          typename Real >
+std::ostream& operator << ( std::ostream& str, const VectorNorm< Dimensions, Real >& f )
+{
+   str << "VectorNorm. function: multiplicator = " << f.getMultiplicator() << " sigma = " << f.getSigma();
+   return str;
+}
+
+} // namespace Analytic
+} // namespace Functions
+} // namespace TNL
+
+
+
+
+
+
diff --git a/src/TNL/Functions/CMakeLists.txt b/src/TNL/Functions/CMakeLists.txt
old mode 100755
new mode 100644
index 04fe4b86805ddbdd11f0d9a73492918db7baeb5d..7727d5539ffb2a475e3c27f3b71b6ba997a23f52
--- a/src/TNL/Functions/CMakeLists.txt
+++ b/src/TNL/Functions/CMakeLists.txt
@@ -14,7 +14,11 @@ SET( headers Domain.h
              MeshFunctionVTKWriter_impl.h             
              OperatorFunction.h
              TestFunction.h             
-             TestFunction_impl.h )
+             TestFunction_impl.h
+             VectorField.h
+             VectorFieldGnuplotWriter.h
+             VectorFieldGnuplotWriter_impl.h
+ )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Functions )
 set( common_SOURCES
diff --git a/src/TNL/Functions/Domain.h b/src/TNL/Functions/Domain.h
index ffef9577dbfabdd1c0338e681b6ef128c23a7f82..07a8c878c214c0baeb4e2677cd2f92cab161ddee 100644
--- a/src/TNL/Functions/Domain.h
+++ b/src/TNL/Functions/Domain.h
@@ -16,7 +16,7 @@ namespace Functions {
 
 enum DomainType { NonspaceDomain, SpaceDomain, MeshDomain, MeshInteriorDomain, MeshBoundaryDomain };
 
-template< int Dimensions,
+template< int Dimension,
           DomainType DomainType_ = SpaceDomain >
 class Domain
 {
@@ -24,7 +24,7 @@ class Domain
  
       typedef void DeviceType;
  
-      static constexpr int getDomainDimensions() { return Dimensions; }
+      static constexpr int getDomainDimension() { return Dimension; }
  
       static constexpr DomainType getDomainType() { return DomainType_; }
 };
diff --git a/src/TNL/Functions/ExactOperatorFunction.h b/src/TNL/Functions/ExactOperatorFunction.h
index 02d9d797287ab9fffe7e14ca138d48368560669c..7561e693b71687bb5f6eaf368c9756e9fcf1499e 100644
--- a/src/TNL/Functions/ExactOperatorFunction.h
+++ b/src/TNL/Functions/ExactOperatorFunction.h
@@ -17,9 +17,9 @@ namespace Functions {
 
 template< typename Operator,
           typename Function >
-class ExactOperatorFunction : public Domain< Operator::getDomainDimensions(), SpaceDomain >
+class ExactOperatorFunction : public Domain< Operator::getDomainDimension(), SpaceDomain >
 {
-   static_assert( Operator::getDomainDimensions() == Function::getDomainDimensions(),
+   static_assert( Operator::getDomainDimension() == Function::getDomainDimension(),
       "Operator and function have different number of domain dimensions." );
  
    public:
@@ -27,9 +27,9 @@ class ExactOperatorFunction : public Domain< Operator::getDomainDimensions(), Sp
       typedef Operator OperatorType;
       typedef Function FunctionType;
       typedef typename FunctionType::RealType RealType;
-      typedef typename FunctionType::VertexType VertexType;
+      typedef typename FunctionType::PointType PointType;
  
-      static constexpr int getDomainDimensions() { return Operator::getDomainDimensions(); }
+      static constexpr int getDomainDimension() { return Operator::getDomainDimension(); }
  
       ExactOperatorFunction(
          const OperatorType& operator_,
@@ -38,7 +38,7 @@ class ExactOperatorFunction : public Domain< Operator::getDomainDimensions(), Sp
  
       __cuda_callable__
       RealType operator()(
-         const VertexType& vertex,
+         const PointType& vertex,
          const RealType& time ) const
       {
          return this->operator_( function, vertex, time );
diff --git a/src/TNL/Functions/FunctionAdapter.h b/src/TNL/Functions/FunctionAdapter.h
index 27b46d93cae78d1e5df5b7164fe59c601850c8ee..425996f5282e26cdf345c9543a5bb24c50ef2575 100644
--- a/src/TNL/Functions/FunctionAdapter.h
+++ b/src/TNL/Functions/FunctionAdapter.h
@@ -29,8 +29,8 @@ class FunctionAdapter
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
-      //typedef typename FunctionType::VertexType VertexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
+      //typedef typename FunctionType::PointType PointType;
  
       template< typename MeshPointer >
       static bool setup( FunctionType& function,
@@ -64,8 +64,8 @@ class FunctionAdapter< Mesh, Function, SpaceDomain >
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
-      typedef typename FunctionType::VertexType VertexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
+      typedef typename FunctionType::PointType PointType;
       
       template< typename MeshPointer >
       static bool setup( FunctionType& function,
@@ -101,8 +101,8 @@ class FunctionAdapter< Mesh, Function, NonspaceDomain >
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
-      typedef typename FunctionType::VertexType VertexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
+      typedef typename FunctionType::PointType PointType;
       
       template< typename MeshPointer >
       static bool setup( FunctionType& function,
@@ -137,7 +137,7 @@ class FunctionAdapter< Mesh, Function, MeshFunction >
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
  
       template< typename EntityType >
       __cuda_callable__ inline
@@ -161,8 +161,8 @@ class FunctionAdapter< Mesh, Function, SpaceDomain >
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
-      typedef typename FunctionType::VertexType VertexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
+      typedef typename FunctionType::PointType PointType;
  
       template< typename EntityType >
       __cuda_callable__ inline
@@ -186,8 +186,8 @@ class FunctionAdapter< Mesh, Function, SpaceDomain >
       typedef Function FunctionType;
       typedef Mesh MeshType;
       typedef typename FunctionType::RealType  RealType;
-      typedef typename MeshType::IndexType     IndexType;
-      typedef typename FunctionType::VertexType VertexType;
+      typedef typename MeshType::GlobalIndexType     IndexType;
+      typedef typename FunctionType::PointType PointType;
  
       template< typename EntityType >
       __cuda_callable__ inline
diff --git a/src/TNL/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h
index f79ae2ed88f8542f76aef01a4dd42692ff790863..2c8d41a564c3af16ad406fbf9dca5cf95f3e98e5 100644
--- a/src/TNL/Functions/MeshFunction.h
+++ b/src/TNL/Functions/MeshFunction.h
@@ -20,11 +20,11 @@ namespace TNL {
 namespace Functions {   
 
 template< typename Mesh,
-          int MeshEntityDimensions = Mesh::meshDimensions,
+          int MeshEntityDimension = Mesh::getMeshDimension(),
           typename Real = typename Mesh::RealType >
 class MeshFunction :
    public Object,
-   public Domain< Mesh::meshDimensions, MeshDomain >
+   public Domain< Mesh::getMeshDimension(), MeshDomain >
 {
    //static_assert( Mesh::DeviceType::DeviceType == Vector::DeviceType::DeviceType,
    //               "Both mesh and vector of a mesh function must reside on the same device.");
@@ -32,13 +32,15 @@ class MeshFunction :
       
       typedef Mesh MeshType;
       typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType IndexType;
+      typedef typename MeshType::GlobalIndexType IndexType;
       typedef SharedPointer< MeshType > MeshPointer;      
       typedef Real RealType;
       typedef Containers::Vector< RealType, DeviceType, IndexType > VectorType;
-      typedef Functions::MeshFunction< Mesh, MeshEntityDimensions, Real > ThisType;
+      typedef Functions::MeshFunction< Mesh, MeshEntityDimension, Real > ThisType;
  
-      static constexpr int getEntitiesDimensions() { return MeshEntityDimensions; }
+      static constexpr int getEntitiesDimension() { return MeshEntityDimension; }
+      
+      static constexpr int getMeshDimension() { return MeshType::getMeshDimension(); }
  
       MeshFunction();
       
@@ -84,7 +86,6 @@ class MeshFunction :
                  const SharedPointer< Vector >& dataPtr,
                  const IndexType& offset = 0 );
       
-      
       void setMesh( const MeshPointer& meshPointer );
       
       template< typename Device = Devices::Host >
@@ -93,6 +94,8 @@ class MeshFunction :
       
       const MeshPointer& getMeshPointer() const;
       
+      static IndexType getDofs( const MeshPointer& meshPointer );
+      
       __cuda_callable__ const VectorType& getData() const;      
       
       __cuda_callable__ VectorType& getData();
@@ -144,7 +147,8 @@ class MeshFunction :
       bool boundLoad( File& file );
  
       bool write( const String& fileName,
-                  const String& format = "vtk" ) const;
+                  const String& format = "vtk",
+                  const double& scale = 1.0 ) const;
  
       using Object::save;
  
@@ -165,5 +169,3 @@ class MeshFunction :
 } // namespace TNL
 
 #include <TNL/Functions/MeshFunction_impl.h>
-#include <TNL/Functions/MeshFunctionGnuplotWriter_impl.h>
-#include <TNL/Functions/MeshFunctionVTKWriter_impl.h>
diff --git a/src/TNL/Functions/MeshFunctionEvaluator.h b/src/TNL/Functions/MeshFunctionEvaluator.h
index 982ed8b9a150d0d33a6211c5d01c87cb8290798b..f4f544d1769523087c396b5691a1be1526bc6d5f 100644
--- a/src/TNL/Functions/MeshFunctionEvaluator.h
+++ b/src/TNL/Functions/MeshFunctionEvaluator.h
@@ -10,7 +10,6 @@
 
 #pragma once
 
-#include <TNL/Meshes/Grid.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Functions/OperatorFunction.h>
 #include <TNL/Functions/FunctionAdapter.h>
@@ -58,7 +57,7 @@ template< typename OutMeshFunction,
           typename InFunction >
 class MeshFunctionEvaluator
 {
-   static_assert( OutMeshFunction::getDomainDimensions() == InFunction::getDomainDimensions(),
+   static_assert( OutMeshFunction::getDomainDimension() == InFunction::getDomainDimension(),
                   "Input and output functions must have the same domain dimensions." );
 
    public:
@@ -162,4 +161,3 @@ class MeshFunctionEvaluatorAdditionEntitiesProcessor
 } // namespace TNL
 
 #include <TNL/Functions/MeshFunctionEvaluator_impl.h>
-
diff --git a/src/TNL/Functions/MeshFunctionEvaluator_impl.h b/src/TNL/Functions/MeshFunctionEvaluator_impl.h
index 205cc979ac9fdabc191fb479443ddb2c9dc8bea7..540ae7077b73baab728c215c425b6bedfc478f1e 100644
--- a/src/TNL/Functions/MeshFunctionEvaluator_impl.h
+++ b/src/TNL/Functions/MeshFunctionEvaluator_impl.h
@@ -115,7 +115,7 @@ evaluateEntities( OutMeshFunctionPointer& meshFunction,
    static_assert( std::is_same< typename std::decay< typename OutMeshFunctionPointer::ObjectType >::type, OutMeshFunction >::value, "expected a smart pointer" );
    static_assert( std::is_same< typename std::decay< typename InFunctionPointer::ObjectType >::type, InFunction >::value, "expected a smart pointer" );
 
-   typedef typename MeshType::template MeshEntity< OutMeshFunction::getEntitiesDimensions() > MeshEntityType;
+   typedef typename MeshType::template EntityType< OutMeshFunction::getEntitiesDimension() > MeshEntityType;
    typedef Functions::MeshFunctionEvaluatorAssignmentEntitiesProcessor< MeshType, TraverserUserData > AssignmentEntitiesProcessor;
    typedef Functions::MeshFunctionEvaluatorAdditionEntitiesProcessor< MeshType, TraverserUserData > AdditionEntitiesProcessor;
    //typedef typename OutMeshFunction::MeshPointer OutMeshPointer;
@@ -171,4 +171,3 @@ evaluateEntities( OutMeshFunctionPointer& meshFunction,
 
 } // namespace Functions
 } // namespace TNL
-
diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter.h b/src/TNL/Functions/MeshFunctionGnuplotWriter.h
index 243577efcb0f45c22a6a15b941a8d4d0e9f4045a..2c21a10328d4bd49bb6f3501246ce476cca83bd2 100644
--- a/src/TNL/Functions/MeshFunctionGnuplotWriter.h
+++ b/src/TNL/Functions/MeshFunctionGnuplotWriter.h
@@ -13,7 +13,7 @@
 #include <TNL/Meshes/Grid.h>
 
 namespace TNL {
-namespace Functions {   
+namespace Functions {
 
 template< typename, int, typename > class MeshFunction;
 
@@ -23,7 +23,8 @@ class MeshFunctionGnuplotWriter
    public:
 
       static bool write( const MeshFunction& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 /***
@@ -41,7 +42,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 /***
@@ -59,9 +61,11 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
+
 /***
  * 2D grids cells
  */
@@ -77,7 +81,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 /***
@@ -95,10 +100,10 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
-
 /***
  * 2D grids vertices
  */
@@ -114,9 +119,69 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+};
+
+
+/***
+ * 3D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::MeshFunction< MeshType, 3, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         std::ostream& str,
+                         const double& scale );
+};
+
+/***
+ * 3D grids faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         std::ostream& str,
+                         const double& scale );
+};
+
+/***
+ * 3D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         std::ostream& str,
+                         const double& scale );
 };
 
 } // namespace Functions
 } // namespace TNL
 
+#include <TNL/Functions/MeshFunctionGnuplotWriter_impl.h>
diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
index a870b86425c3b26f513d1fd1d6e94a89c36bba68..13c8fa1cb0da1c280a7eb605a0f31f0f7c2a13e8 100644
--- a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
+++ b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
@@ -10,14 +10,17 @@
 
 #pragma once
 
+#include <TNL/Functions/MeshFunctionGnuplotWriter.h>
+
 namespace TNL {
-namespace Functions {    
+namespace Functions {
 
 template< typename MeshFunction >
 bool
 MeshFunctionGnuplotWriter< MeshFunction >::
 write( const MeshFunction& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    std::cerr << "Gnuplot writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl;
    return false;
@@ -33,7 +36,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typename MeshType::Cell entity( mesh );
@@ -42,9 +46,9 @@ write( const MeshFunctionType& function,
         entity.getCoordinates().x() ++ )
    {
       entity.refresh();
-      typename MeshType::VertexType v = entity.getCenter();
-      str << v << " "
-          << function.getData().getElement( entity.getIndex() ) << std::endl;
+      typename MeshType::PointType v = entity.getCenter();
+      str << v.x() << " "
+          << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
 }
@@ -59,7 +63,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typename MeshType::Vertex entity( mesh );
@@ -68,9 +73,9 @@ write( const MeshFunctionType& function,
         entity.getCoordinates().x() ++ )
    {
       entity.refresh();
-      typename MeshType::VertexType v = entity.getCenter();
-      str << v << " "
-          << function.getData().getElement( entity.getIndex() ) << std::endl;
+      typename MeshType::PointType v = entity.getCenter();
+      str << v.x() << " "
+          << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
 }
@@ -86,7 +91,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typename MeshType::Cell entity( mesh );
@@ -99,9 +105,9 @@ write( const MeshFunctionType& function,
            entity.getCoordinates().x() ++ )
       {
          entity.refresh();
-         typename MeshType::VertexType v = entity.getCenter();
+         typename MeshType::PointType v = entity.getCenter();
          str << v.x() << " " << v.y() << " "
-             << function.getData().getElement( entity.getIndex() ) << std::endl;
+             << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
       }
       str << std::endl;
    }
@@ -118,13 +124,14 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typedef typename MeshType::Face EntityType;
    typedef typename EntityType::EntityOrientationType EntityOrientation;
    EntityType entity( mesh );
- 
+
    entity.setOrientation( EntityOrientation( 1.0, 0.0 ) );
    for( entity.getCoordinates().y() = 0;
         entity.getCoordinates().y() < mesh.getDimensions().y();
@@ -135,13 +142,13 @@ write( const MeshFunctionType& function,
            entity.getCoordinates().x() ++ )
       {
          entity.refresh();
-         typename MeshType::VertexType v = entity.getCenter();
+         typename MeshType::PointType v = entity.getCenter();
          str << v.x() << " " << v.y() << " "
-             << function.getData().getElement( entity.getIndex() ) << std::endl;
+             << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
       }
       str << std::endl;
    }
- 
+
    entity.setOrientation( EntityOrientation( 0.0, 1.0 ) );
          for( entity.getCoordinates().x() = 0;
            entity.getCoordinates().x() < mesh.getDimensions().x();
@@ -154,9 +161,9 @@ write( const MeshFunctionType& function,
 
       {
          entity.refresh();
-         typename MeshType::VertexType v = entity.getCenter();
+         typename MeshType::PointType v = entity.getCenter();
          str << v.x() << " " << v.y() << " "
-             << function.getData().getElement( entity.getIndex() ) << std::endl;
+             << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
       }
       str << std::endl;
    }
@@ -174,7 +181,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typename MeshType::Vertex entity( mesh );
@@ -187,15 +195,169 @@ write( const MeshFunctionType& function,
            entity.getCoordinates().x() ++ )
       {
          entity.refresh();
-         typename MeshType::VertexType v = entity.getCenter();
+         typename MeshType::PointType v = entity.getCenter();
          str << v.x() << " " << v.y() << " "
-             << function.getData().getElement( entity.getIndex() ) << std::endl;
+             << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
       }
       str << std::endl;
    }
    return true;
 }
 
+
+/****
+ * 3D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
+write( const MeshFunctionType& function,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = function.getMesh();
+   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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z() << " "
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
+/****
+ * 3D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
+write( const MeshFunctionType& function,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = function.getMesh();
+   typedef typename MeshType::Face EntityType;
+   typedef typename EntityType::EntityOrientationType EntityOrientation;
+   EntityType entity( mesh );
+
+   entity.setOrientation( EntityOrientation( 1.0, 0.0, 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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z() << " "
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
+         }
+         str << 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().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         for( entity.getCoordinates().y() = 0;
+              entity.getCoordinates().y() <= mesh.getDimensions().y();
+              entity.getCoordinates().y() ++ )
+         {
+            entity.refresh();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z() << " "
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
+         }
+         str << std::endl;
+      }
+
+   entity.setOrientation( EntityOrientation( 0.0, 0.0, 1.0 ) );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() < mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+      for( entity.getCoordinates().y() = 0;
+           entity.getCoordinates().y() <= mesh.getDimensions().y();
+           entity.getCoordinates().y() ++ )
+      {
+         for( entity.getCoordinates().z() = 0;
+              entity.getCoordinates().z() < mesh.getDimensions().z();
+              entity.getCoordinates().z() ++ )
+         {
+            entity.refresh();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z() << " "
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
+
+/****
+ * 3D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = function.getMesh();
+   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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z() << " "
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
 } // namespace Functions
 } // namespace TNL
 
diff --git a/src/TNL/Functions/MeshFunctionNormGetter.h b/src/TNL/Functions/MeshFunctionNormGetter.h
index dd696b579c9677fb60127023e354f6b3e91d3acf..50e39c6de767fa79828d7e4bc9c488356c1d5be6 100644
--- a/src/TNL/Functions/MeshFunctionNormGetter.h
+++ b/src/TNL/Functions/MeshFunctionNormGetter.h
@@ -23,18 +23,18 @@ class MeshFunctionNormGetter
  * Specialization for grids
  * TODO: implement this even for other devices
  */
-template< int Dimensions,
+template< int Dimension,
           typename MeshReal,
           typename MeshIndex,
-          int EntityDimensions,
+          int EntityDimension,
           typename Real >
-class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal, Devices::Host, MeshIndex >, EntityDimensions, Real >,
-                                 Meshes::Grid< Dimensions, MeshReal, Devices::Host, MeshIndex > >
+class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimension, MeshReal, Devices::Host, MeshIndex >, EntityDimension, Real >,
+                                 Meshes::Grid< Dimension, MeshReal, Devices::Host, MeshIndex > >
 {
    public:
  
-      typedef Functions::MeshFunction< Meshes::Grid< Dimensions, MeshReal, Devices::Host, MeshIndex >, EntityDimensions, Real > MeshFunctionType;
-      typedef Meshes::Grid< Dimensions, MeshReal, Devices::Host, MeshIndex > GridType;
+      typedef Functions::MeshFunction< Meshes::Grid< Dimension, MeshReal, Devices::Host, MeshIndex >, EntityDimension, Real > MeshFunctionType;
+      typedef Meshes::Grid< Dimension, MeshReal, Devices::Host, MeshIndex > GridType;
       typedef MeshReal MeshRealType;
       typedef Devices::Host DeviceType;
       typedef MeshIndex MeshIndexType;
@@ -45,7 +45,7 @@ class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal,
       static RealType getNorm( const MeshFunctionType& function,
                                const RealType& p )
       {
-         if( EntityDimensions == Dimensions )
+         if( EntityDimension == Dimension )
          {
             if( p == 1.0 )
                return function.getMesh().getCellMeasure() * function.getData().lpNorm( 1.0 );
@@ -53,7 +53,7 @@ class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal,
                return std::sqrt( function.getMesh().getCellMeasure() ) * function.getData().lpNorm( 2.0 );
             return std::pow( function.getMesh().getCellMeasure(), 1.0 / p ) * function.getData().lpNorm( p );
          }
-         if( EntityDimensions > 0 )
+         if( EntityDimension > 0 )
          {
             if( p == 1.0 )
             {
@@ -102,18 +102,18 @@ class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal,
 /****
  * Specialization for CUDA devices
  */
-template< int Dimensions,
+template< int Dimension,
           typename MeshReal,
           typename MeshIndex,
-          int EntityDimensions,
+          int EntityDimension,
           typename Real >
-class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal, Devices::Cuda, MeshIndex >, EntityDimensions, Real >,
-                                 Meshes::Grid< Dimensions, MeshReal, Devices::Cuda, MeshIndex > >
+class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimension, MeshReal, Devices::Cuda, MeshIndex >, EntityDimension, Real >,
+                                 Meshes::Grid< Dimension, MeshReal, Devices::Cuda, MeshIndex > >
 {
    public:
  
-      typedef Functions::MeshFunction< Meshes::Grid< Dimensions, MeshReal, Devices::Cuda, MeshIndex >, EntityDimensions, Real > MeshFunctionType;
-      typedef Meshes::Grid< Dimensions, MeshReal, Devices::Cuda, MeshIndex > GridType;
+      typedef Functions::MeshFunction< Meshes::Grid< Dimension, MeshReal, Devices::Cuda, MeshIndex >, EntityDimension, Real > MeshFunctionType;
+      typedef Meshes::Grid< Dimension, MeshReal, Devices::Cuda, MeshIndex > GridType;
       typedef MeshReal MeshRealType;
       typedef Devices::Cuda DeviceType;
       typedef MeshIndex MeshIndexType;
@@ -124,7 +124,7 @@ class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal,
       static RealType getNorm( const MeshFunctionType& function,
                                const RealType& p )
       {
-         if( EntityDimensions == Dimensions )
+         if( EntityDimension == Dimension )
          {
             if( p == 1.0 )
                return function.getMesh().getCellMeasure() * function.getData().lpNorm( 1.0 );
@@ -132,9 +132,9 @@ class MeshFunctionNormGetter< MeshFunction< Meshes::Grid< Dimensions, MeshReal,
                return ::sqrt( function.getMesh().getCellMeasure() ) * function.getData().lpNorm( 2.0 );
             return ::pow( function.getMesh().getCellMeasure(), 1.0 / p ) * function.getData().lpNorm( p );
          }
-         if( EntityDimensions > 0 )
+         if( EntityDimension > 0 )
          {
-            Assert( false, std::cerr << "Not implemented yet." << std::endl );
+            TNL_ASSERT_TRUE( false, "Not implemented yet." );
          }
  
          if( p == 1.0 )
diff --git a/src/TNL/Functions/MeshFunctionVTKWriter.h b/src/TNL/Functions/MeshFunctionVTKWriter.h
index 239b62f3795b2b373f4725aab699516080778763..b4d18e4490901c2824ff922fe10f18607198e780 100644
--- a/src/TNL/Functions/MeshFunctionVTKWriter.h
+++ b/src/TNL/Functions/MeshFunctionVTKWriter.h
@@ -10,16 +10,22 @@
 
 #pragma once
 
+#include <TNL/Meshes/Grid.h>
+
 namespace TNL {
 namespace Functions {   
 
+template< typename, int, typename > class MeshFunction;
+
 template< typename MeshFunction >
 class MeshFunctionVTKWriter
 {
    public:
  
       static bool write( const MeshFunction& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunction& function,
                          std::ostream& str ){}
 };
@@ -39,7 +45,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -59,7 +67,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -79,7 +89,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -99,7 +111,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -119,7 +133,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -139,7 +155,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 3, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -159,7 +177,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -179,7 +199,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -199,7 +221,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
+      
       static void writeHeader(const MeshFunctionType& function,
                          std::ostream& str );
 };
@@ -207,3 +231,4 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me
 } // namespace Functions
 } // namespace TNL
 
+#include <TNL/Functions/MeshFunctionVTKWriter_impl.h>
diff --git a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
index 0493b0a421c973c110a661364ce4aa9814fc30c8..606eac9ce348e2260109845af0bb05cea064a3e8 100644
--- a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
+++ b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Functions/MeshFunctionVTKWriter.h>
+
 namespace TNL {
 namespace Functions {   
 
@@ -17,7 +19,8 @@ template< typename MeshFunction >
 bool
 MeshFunctionVTKWriter< MeshFunction >::
 write( const MeshFunction& function,
-                         std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    std::cerr << "VTK writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl;
    return false;
@@ -34,11 +37,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -52,7 +55,8 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    writeHeader(function, str);
  
@@ -61,7 +65,6 @@ write( const MeshFunctionType& function,
    const RealType spaceStep = mesh.getSpaceSteps().x();
  
    str << "POINTS " << mesh.getDimensions().x() + 1 << " float" << std::endl;
- 
    for (int i = 0; i <= mesh.getDimensions().x(); i++)
    {
        str << origin + i * spaceStep << " 0 0" << std::endl;
@@ -83,13 +86,11 @@ write( const MeshFunctionType& function,
    str << "SCALARS cellFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Cell entity( mesh );
-   for( entity.getCoordinates().x() = 0;
-        entity.getCoordinates().x() < mesh.getDimensions().x();
-        entity.getCoordinates().x() ++ )
+   for( MeshIndex i = 0; i < mesh.template getEntitiesCount< typename MeshType::Cell >(); i++ )
    {
+      typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i );
       entity.refresh();
-      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
  
    return true;
@@ -106,11 +107,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -124,7 +125,8 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    writeHeader(function, str);
  
@@ -133,7 +135,6 @@ write( const MeshFunctionType& function,
    const RealType spaceStep = mesh.getSpaceSteps().x();
  
    str << "POINTS " << mesh.getDimensions().x() + 1 << " float" << std::endl;
- 
    for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
    {
        str << origin + i * spaceStep << " 0 0" << std::endl;
@@ -155,13 +156,11 @@ write( const MeshFunctionType& function,
    str << "SCALARS VerticesFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Vertex entity( mesh );
-   for( entity.getCoordinates().x() = 0;
-        entity.getCoordinates().x() <= mesh.getDimensions().x();
-        entity.getCoordinates().x() ++ )
+   for( MeshIndex i = 0; i < mesh.template getEntitiesCount< typename MeshType::Vertex >(); i++ )
    {
+      typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i );
       entity.refresh();
-      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
  
    return true;
@@ -178,11 +177,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -196,7 +195,8 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    writeHeader(function, str);
  
@@ -205,9 +205,10 @@ write( const MeshFunctionType& function,
    const RealType spaceStepX = mesh.getSpaceSteps().x();
    const RealType originY = mesh.getOrigin().y();
    const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
+   const MeshIndex entitiesCount = mesh.template getEntitiesCount< typename MeshType::Cell >();
  
-   str << "POINTS " << (mesh.getDimensions().x() + 1) * (mesh.getDimensions().y() + 1) << " float" << std::endl;
- 
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int j = 0; j < mesh.getDimensions().y() + 1; j++)
    {
         for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
@@ -216,8 +217,7 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELLS " << mesh.getDimensions().x() * mesh.getDimensions().y() << " " <<
-          mesh.getDimensions().x() * mesh.getDimensions().y() * 5 << std::endl;
+   str << std::endl << "CELLS " << entitiesCount << " " << entitiesCount * 5 << std::endl;
    for (int j = 0; j < mesh.getDimensions().y(); j++)
    {
         for (int i = 0; i < mesh.getDimensions().x(); i++)
@@ -233,23 +233,17 @@ write( const MeshFunctionType& function,
        str << "8 " << std::endl;
    }
  
-   str << std::endl << "CELL_DATA " << mesh.getDimensions().x() * mesh.getDimensions().y() << std::endl;
+   str << std::endl << "CELL_DATA " << entitiesCount << std::endl;
    str << "SCALARS cellFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Cell entity( mesh );
-   for( entity.getCoordinates().y() = 0;
-        entity.getCoordinates().y() < mesh.getDimensions().y();
-        entity.getCoordinates().y() ++ )
+   for( MeshIndex i = 0; i < entitiesCount; i++ )
    {
-      for( entity.getCoordinates().x() = 0;
-           entity.getCoordinates().x() < mesh.getDimensions().x();
-           entity.getCoordinates().x() ++ )
-      {
-         entity.refresh();
-         str << function.getData().getElement( entity.getIndex() ) << std::endl;
-      }
+      typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
+
    return true;
 }
 
@@ -264,11 +258,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -282,10 +276,11 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
-   typedef typename MeshType::template MeshEntity< 0 > Vertex;
-   typedef typename MeshType::template MeshEntity< 1 > Face;
+   typedef typename MeshType::template EntityType< 0 > Vertex;
+   typedef typename MeshType::template EntityType< 1 > Face;
    writeHeader(function, str);
  
    const MeshType& mesh = function.getMesh();
@@ -293,9 +288,10 @@ write( const MeshFunctionType& function,
    const RealType spaceStepX = mesh.getSpaceSteps().x();
    const RealType originY = mesh.getOrigin().y();
    const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
+   const MeshIndex entitiesCount = mesh.template getEntitiesCount< typename MeshType::Face >();
  
-   str << "POINTS " << mesh.template getEntitiesCount< Vertex >() << " float" << std::endl;
- 
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int j = 0; j < ( mesh.getDimensions().y() + 1); j++)
    {
         for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
@@ -304,8 +300,7 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELLS " << mesh.template getEntitiesCount< Face >() << " " <<
-          mesh.template getEntitiesCount< Face >() * 3 << std::endl;
+   str << std::endl << "CELLS " << entitiesCount << " " << entitiesCount * 3 << std::endl;
    for (int j = 0; j < mesh.getDimensions().y(); j++)
    {
         for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
@@ -322,49 +317,23 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELL_TYPES " << mesh.template getEntitiesCount< Face >() << std::endl;
-   for (int i = 0; i < mesh.template getEntitiesCount< Face >(); i++)
+   str << std::endl << "CELL_TYPES " << entitiesCount << std::endl;
+   for (int i = 0; i < entitiesCount; i++)
    {
        str << "3" << std::endl;
    }
  
-   str << std::endl << "CELL_DATA " << mesh.template getEntitiesCount< Face >() << std::endl;
+   str << std::endl << "CELL_DATA " << entitiesCount << std::endl;
    str << "SCALARS FaceslFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::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( MeshIndex i = 0; i < entitiesCount; i++ )
    {
-      for( entity.getCoordinates().x() = 0;
-           entity.getCoordinates().x() <= mesh.getDimensions().x();
-           entity.getCoordinates().x() ++ )
-      {
-         entity.refresh();
-         str << function.getData().getElement( entity.getIndex() ) << std::endl;
-      }
+      typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i );
+      entity.refresh();
+      str << scale * 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;
 }
 
@@ -379,11 +348,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -397,9 +366,10 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
-   typedef typename MeshType::template MeshEntity< 0 > Vertex;
+   typedef typename MeshType::template EntityType< 0 > Vertex;
    writeHeader(function, str);
  
    const MeshType& mesh = function.getMesh();
@@ -407,10 +377,9 @@ write( const MeshFunctionType& function,
    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" << std::endl;
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
  
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int j = 0; j < ( mesh.getDimensions().y() + 1); j++)
    {
         for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
@@ -419,8 +388,7 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELLS " << mesh.template getEntitiesCount< Vertex >() << " " <<
-          mesh.template getEntitiesCount< Vertex >() * 2 << std::endl;
+   str << std::endl << "CELLS " << verticesCount << " " << verticesCount * 2 << std::endl;
    for (int j = 0; j < ( mesh.getDimensions().y() + 1 ); j++)
    {
         for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
@@ -429,30 +397,23 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELL_TYPES " << mesh.template getEntitiesCount< Vertex >() << std::endl;
-   for (int i = 0; i < mesh.template getEntitiesCount< Vertex >(); i++)
+   str << std::endl << "CELL_TYPES " << verticesCount << std::endl;
+   for (int i = 0; i < verticesCount; i++)
    {
        str << "1" << std::endl;
    }
  
-   str << std::endl << "CELL_DATA " << mesh.template getEntitiesCount< Vertex >() << std::endl;
+   str << std::endl << "CELL_DATA " << verticesCount << std::endl;
    str << "SCALARS VerticesFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Vertex entity( mesh );
-   for( entity.getCoordinates().y() = 0;
-        entity.getCoordinates().y() <= mesh.getDimensions().y();
-        entity.getCoordinates().y() ++ )
+   for( MeshIndex i = 0; i < verticesCount; i++ )
    {
-      for( entity.getCoordinates().x() = 0;
-           entity.getCoordinates().x() <= mesh.getDimensions().x();
-           entity.getCoordinates().x() ++ )
-      {
-         entity.refresh();
-         str << function.getData().getElement( entity.getIndex() ) << std::endl;
-      }
+      typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
- 
+
    return true;
 }
 
@@ -467,11 +428,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -485,7 +446,8 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    writeHeader(function, str);
  
@@ -496,11 +458,10 @@ write( const MeshFunctionType& function,
    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" << std::endl;
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
+   const MeshIndex entitiesCount = mesh.template getEntitiesCount< typename MeshType::Cell >();
  
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int k = 0; k <= mesh.getDimensions().y(); k++)
    {
        for (int j = 0; j <= mesh.getDimensions().y(); j++)
@@ -543,24 +504,13 @@ write( const MeshFunctionType& function,
    str << "SCALARS cellFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Cell entity( mesh );
-   for( entity.getCoordinates().z() = 0;
-        entity.getCoordinates().z() < mesh.getDimensions().z();
-        entity.getCoordinates().z() ++ )
+   for( MeshIndex i = 0; i < entitiesCount; i++ )
    {
-        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;
-            }
-        }
+      typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
+
    return true;
 }
 
@@ -575,11 +525,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -593,10 +543,9 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
-   typedef typename MeshType::template MeshEntity< 2 > Face;
-   typedef typename MeshType::template MeshEntity< 3 > Cell;
    writeHeader(function, str);
  
    const MeshType& mesh = function.getMesh();
@@ -606,12 +555,10 @@ write( const MeshFunctionType& function,
    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" << std::endl;
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
+   const MeshIndex entitiesCount = mesh.template getEntitiesCount< typename MeshType::Face >();
  
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int k = 0; k <= mesh.getDimensions().y(); k++)
    {
        for (int j = 0; j <= mesh.getDimensions().y(); j++)
@@ -624,8 +571,7 @@ write( const MeshFunctionType& function,
        }
    }
  
-   str << std::endl << "CELLS " << entitiesCount << " " <<
-          entitiesCount * 5 << std::endl;
+   str << std::endl << "CELLS " << entitiesCount << " " << entitiesCount * 5 << std::endl;
    for (int k = 0; k < mesh.getDimensions().z(); k++)
    {
         for (int j = 0; j < mesh.getDimensions().y(); j++)
@@ -678,67 +624,13 @@ write( const MeshFunctionType& function,
    str << "SCALARS facesFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::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( MeshIndex i = 0; i < entitiesCount; i++ )
    {
-        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;
-            }
-        }
+      typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
- 
+
    return true;
 }
 
@@ -753,11 +645,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 1, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -771,10 +663,9 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 1, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
-   typedef typename MeshType::template MeshEntity< 1 > Edge;
-   typedef typename MeshType::template MeshEntity< 3 > Cell;
    writeHeader(function, str);
  
    const MeshType& mesh = function.getMesh();
@@ -784,12 +675,10 @@ write( const MeshFunctionType& function,
    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" << std::endl;
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
+   const MeshIndex entitiesCount = mesh.template getEntitiesCount< typename MeshType::Edge >();
  
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int k = 0; k <= mesh.getDimensions().y(); k++)
    {
        for (int j = 0; j <= mesh.getDimensions().y(); j++)
@@ -802,8 +691,7 @@ write( const MeshFunctionType& function,
        }
    }
  
-   str << std::endl << "CELLS " << entitiesCount << " " <<
-          entitiesCount * 3 << std::endl;
+   str << std::endl << "CELLS " << entitiesCount << " " << entitiesCount * 3 << std::endl;
    for (int k = 0; k <= mesh.getDimensions().z(); k++)
    {
         for (int j = 0; j <= mesh.getDimensions().y(); j++)
@@ -850,67 +738,13 @@ write( const MeshFunctionType& function,
    str << "SCALARS edgesFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::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( MeshIndex i = 0; i < entitiesCount; i++ )
    {
-        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;
-            }
-        }
+      typename MeshType::Edge entity = mesh.template getEntity< typename MeshType::Edge >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
- 
+
    return true;
 }
 
@@ -925,11 +759,11 @@ template< typename MeshReal,
 void
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >::
 writeHeader( const MeshFunctionType& function,
-       std::ostream& str )
+             std::ostream& str )
 {
     const MeshType& mesh = function.getMesh();
-    const typename MeshType::VertexType& origin = mesh.getOrigin();
-    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    const typename MeshType::PointType& origin = mesh.getOrigin();
+    const typename MeshType::PointType& proportions = mesh.getProportions();
     str << "# vtk DataFile Version 2.0" << std::endl;
     str << "TNL DATA" << std::endl;
     str << "ASCII" << std::endl;
@@ -943,9 +777,9 @@ template< typename MeshReal,
 bool
 MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
-   typedef typename MeshType::template MeshEntity< 0 > Vertex;
    writeHeader(function, str);
  
    const MeshType& mesh = function.getMesh();
@@ -955,9 +789,9 @@ write( const MeshFunctionType& function,
    const RealType spaceStepY = mesh.getSpaceSteps().y();
    const RealType originZ = mesh.getOrigin().z();
    const RealType spaceStepZ = mesh.getSpaceSteps().z();
+   const MeshIndex verticesCount = mesh.template getEntitiesCount< typename MeshType::Vertex >();
  
-   str << "POINTS " << mesh.template getEntitiesCount< Vertex >() << " float" << std::endl;
- 
+   str << "POINTS " << verticesCount << " float" << std::endl;
    for (int k = 0; k <= mesh.getDimensions().y(); k++)
    {
        for (int j = 0; j <= mesh.getDimensions().y(); j++)
@@ -970,8 +804,7 @@ write( const MeshFunctionType& function,
        }
    }
  
-   str << std::endl << "CELLS " << mesh.template getEntitiesCount< Vertex >() << " " <<
-          mesh.template getEntitiesCount< Vertex >() * 2 << std::endl;
+   str << std::endl << "CELLS " << verticesCount << " " << verticesCount * 2 << std::endl;
    for (int k = 0; k < ( mesh.getDimensions().z() + 1 ); k++)
    {
         for (int j = 0; j < ( mesh.getDimensions().y() + 1 ); j++)
@@ -983,35 +816,23 @@ write( const MeshFunctionType& function,
         }
    }
  
-   str << std::endl << "CELL_TYPES " << mesh.template getEntitiesCount< Vertex >() << std::endl;
-   for (int i = 0; i < mesh.template getEntitiesCount< Vertex >(); i++)
+   str << std::endl << "CELL_TYPES " << verticesCount << std::endl;
+   for (int i = 0; i < verticesCount; i++)
    {
        str << "1" << std::endl;
    }
  
-   str << std::endl << "CELL_DATA " << mesh.template getEntitiesCount< Vertex >() << std::endl;
+   str << std::endl << "CELL_DATA " << verticesCount << std::endl;
    str << "SCALARS verticesFunctionValues float 1" << std::endl;
    str << "LOOKUP_TABLE default" << std::endl;
 
-   typename MeshType::Vertex entity( mesh );
-   for( entity.getCoordinates().z() = 0;
-        entity.getCoordinates().z() <= mesh.getDimensions().z();
-        entity.getCoordinates().z() ++ )
+   for( MeshIndex i = 0; i < verticesCount; i++ )
    {
-        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;
-            }
-        }
+      typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i );
+      entity.refresh();
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
- 
+
    return true;
 }
 
diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h
index f41cc28a0bc1aff4a3b60e9b8ef3668452197848..7164170f1ab51a20bcdeaeb9011cb97bb97b4590 100644
--- a/src/TNL/Functions/MeshFunction_impl.h
+++ b/src/TNL/Functions/MeshFunction_impl.h
@@ -22,122 +22,122 @@ namespace TNL {
 namespace Functions {   
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 MeshFunction()
 {
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 MeshFunction( const MeshPointer& meshPointer )
 : meshPointer( meshPointer )
 {
-   this->data.setSize( meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );
+   this->data.setSize( getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 MeshFunction( const ThisType& meshFunction )
-: meshPointer( meshPointer )
+: meshPointer( meshFunction.meshPointer )
 {
    this->data.bind( meshFunction.getData() );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Vector >
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 MeshFunction( const MeshPointer& meshPointer,
               Vector& data,
               const IndexType& offset )
 : meshPointer( meshPointer )
 {
-   this->data.bind( data, offset, meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );   
+   this->data.bind( data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );   
 }
 
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Vector >
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 MeshFunction( const MeshPointer& meshPointer,
               SharedPointer< Vector >& data,
               const IndexType& offset )
 : meshPointer( meshPointer )
 {
-   this->data.bind( *data, offset, meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );   
+   this->data.bind( *data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );   
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 String
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getType()
 {
    return String( "Functions::MeshFunction< " ) +
                      Mesh::getType() + ", " +
-                     String( MeshEntityDimensions ) + ", " +
+                     String( MeshEntityDimension ) + ", " +
                     TNL::getType< Real >() +
                      " >";
 };
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 String
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getTypeVirtual() const
 {
    return this->getType();
 };
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 String
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getSerializationType()
 {
    return String( "Functions::MeshFunction< " ) +
                      Mesh::getSerializationType() + ", " +
-                     String( MeshEntityDimensions ) + ", " +
+                     String( MeshEntityDimension ) + ", " +
                     TNL::getType< Real >() +
                      " >";
 };
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 String
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
@@ -145,10 +145,10 @@ configSetup( Config::ConfigDescription& config,
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 setup( const MeshPointer& meshPointer,
        const Config::ParameterContainer& parameters,
        const String& prefix )
@@ -163,16 +163,17 @@ setup( const MeshPointer& meshPointer,
    else
    {
       std::cerr << "Missing parameter " << prefix << "file." << std::endl;
+      throw(0);
       return false;
    }
    return true;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 bind( ThisType& meshFunction )
 {
    this->meshPointer = meshFunction.getMeshPointer();
@@ -180,199 +181,209 @@ bind( ThisType& meshFunction )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Vector >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 bind( const MeshPointer& meshPointer,
       const Vector& data,
       const IndexType& offset )
 {
    this->meshPointer = meshPointer;
-   this->data.bind( data, offset, meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );   
+   this->data.bind( data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );   
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Vector >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 bind( const MeshPointer& meshPointer,
       const SharedPointer< Vector >& data,
       const IndexType& offset )
 {
    this->meshPointer = meshPointer;
-   this->data.bind( *data, offset, meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );   
+   this->data.bind( *data, offset, getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );   
 }
 
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 setMesh( const MeshPointer& meshPointer )
 {
    this->meshPointer = meshPointer;
-   this->data.setSize( meshPointer->template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );   
+   this->data.setSize( getMesh().template getEntitiesCount< typename Mesh::template EntityType< MeshEntityDimension > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );   
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
  template< typename Device >
 __cuda_callable__
-const typename MeshFunction< Mesh, MeshEntityDimensions, Real >::MeshType& 
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+const typename MeshFunction< Mesh, MeshEntityDimension, Real >::MeshType& 
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getMesh() const
 {
    return this->meshPointer.template getData< Device >();
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
-const typename MeshFunction< Mesh, MeshEntityDimensions, Real >::MeshPointer&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+const typename MeshFunction< Mesh, MeshEntityDimension, Real >::MeshPointer&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getMeshPointer() const
 {
    return this->meshPointer;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
+          typename Real >
+typename MeshFunction< Mesh, MeshEntityDimension, Real >::IndexType
+MeshFunction< Mesh, MeshEntityDimension, Real >::
+getDofs( const MeshPointer& meshPointer )
+{
+   return meshPointer->template getEntitiesCount< getEntitiesDimension() >();
+}
+
+template< typename Mesh,
+          int MeshEntityDimension,
           typename Real >
 __cuda_callable__
-const typename MeshFunction< Mesh, MeshEntityDimensions, Real >::VectorType& 
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+const typename MeshFunction< Mesh, MeshEntityDimension, Real >::VectorType& 
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getData() const
 {
    return this->data;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 __cuda_callable__
-typename MeshFunction< Mesh, MeshEntityDimensions, Real >::VectorType& 
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+typename MeshFunction< Mesh, MeshEntityDimension, Real >::VectorType& 
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getData()
 {
    return this->data;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 refresh( const RealType& time ) const
 {
    return true;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 deepRefresh( const RealType& time ) const
 {
    return true;
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename EntityType >
-typename Functions::MeshFunction< Mesh, MeshEntityDimensions, Real >::RealType
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+typename Functions::MeshFunction< Mesh, MeshEntityDimension, Real >::RealType
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getValue( const EntityType& meshEntity ) const
 {
-   static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
+   static_assert( EntityType::getEntityDimension() == MeshEntityDimension, "Calling with wrong EntityType -- entity dimensions do not match." );
    return this->data.getValue( meshEntity.getIndex() );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename EntityType >
 void
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 setValue( const EntityType& meshEntity,
           const RealType& value )
 {
-   static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
+   static_assert( EntityType::getEntityDimension() == MeshEntityDimension, "Calling with wrong EntityType -- entity dimensions do not match." );
    this->data.setValue( meshEntity.getIndex(), value );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename EntityType >
 __cuda_callable__
-typename Functions::MeshFunction< Mesh, MeshEntityDimensions, Real >::RealType&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+typename Functions::MeshFunction< Mesh, MeshEntityDimension, Real >::RealType&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator()( const EntityType& meshEntity,
             const RealType& time )
 {
-   static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
+   static_assert( EntityType::getEntityDimension() == MeshEntityDimension, "Calling with wrong EntityType -- entity dimensions do not match." );
    return this->data[ meshEntity.getIndex() ];
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename EntityType >
 __cuda_callable__
-const typename Functions::MeshFunction< Mesh, MeshEntityDimensions, Real >::RealType&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+const typename Functions::MeshFunction< Mesh, MeshEntityDimension, Real >::RealType&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator()( const EntityType& meshEntity,
             const RealType& time ) const
 {
-   static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
+   static_assert( EntityType::getEntityDimension() == MeshEntityDimension, "Calling with wrong EntityType -- entity dimensions do not match." );
    return this->data[ meshEntity.getIndex() ];
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 __cuda_callable__
-typename Functions::MeshFunction< Mesh, MeshEntityDimensions, Real >::RealType&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+typename Functions::MeshFunction< Mesh, MeshEntityDimension, Real >::RealType&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator[]( const IndexType& meshEntityIndex )
 {
    return this->data[ meshEntityIndex ];
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 __cuda_callable__
-const typename Functions::MeshFunction< Mesh, MeshEntityDimensions, Real >::RealType&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+const typename Functions::MeshFunction< Mesh, MeshEntityDimension, Real >::RealType&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator[]( const IndexType& meshEntityIndex ) const
 {
    return this->data[ meshEntityIndex ];
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Function >
-MeshFunction< Mesh, MeshEntityDimensions, Real >&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator = ( const Function& f )
 {
    DevicePointer< ThisType > thisDevicePtr( *this );
@@ -382,11 +393,11 @@ operator = ( const Function& f )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Function >
-MeshFunction< Mesh, MeshEntityDimensions, Real >&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator += ( const Function& f )
 {
    DevicePointer< ThisType > thisDevicePtr( *this );
@@ -396,11 +407,11 @@ operator += ( const Function& f )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
    template< typename Function >
-MeshFunction< Mesh, MeshEntityDimensions, Real >&
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >&
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 operator -= ( const Function& f )
 {
    DevicePointer< ThisType > thisDevicePtr( *this );
@@ -410,52 +421,52 @@ operator -= ( const Function& f )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 Real
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getLpNorm( const RealType& p ) const
 {
    return MeshFunctionNormGetter< ThisType >::getNorm( *this, p );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 Real
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 getMaxNorm() const
 {
    return this->data.absMax();
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 save( File& file ) const
 {
-   Assert( this->data.getSize() == this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >(), 
-      std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
-                << "this->mesh->template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() = " << this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >() );
+   TNL_ASSERT( this->data.getSize() == this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), 
+               std::cerr << "this->data.getSize() = " << this->data.getSize() << std::endl
+                         << "this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() = " << this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >() );
    if( ! Object::save( file ) )
       return false;
    return this->data.save( file );
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 load( File& file )
 {
    if( ! Object::load( file ) )
       return false;
    if( ! this->data.load( file ) )
       return false;
-   const IndexType meshSize = this->meshPointer.getData().template getEntitiesCount< typename MeshType::template MeshEntity< MeshEntityDimensions > >();
+   const IndexType meshSize = this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >();
    if( this->data.getSize() != meshSize )
    {      
       std::cerr << "Size of the data loaded to the mesh function (" << this->data.getSize() << ") does not fit with the mesh size (" << meshSize << ")." << std::endl;
@@ -465,10 +476,10 @@ load( File& file )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 boundLoad( File& file )
 {
    if( ! Object::load( file ) )
@@ -477,24 +488,29 @@ boundLoad( File& file )
 }
 
 template< typename Mesh,
-          int MeshEntityDimensions,
+          int MeshEntityDimension,
           typename Real >
 bool
-MeshFunction< Mesh, MeshEntityDimensions, Real >::
+MeshFunction< Mesh, MeshEntityDimension, Real >::
 write( const String& fileName,
-       const String& format ) const
+       const String& format,
+       const double& scale ) const
 {
    std::fstream file;
    file.open( fileName.getString(), std::ios::out );
    if( ! file )
    {
-      std::cerr << "Unbable to open a file " << fileName << "." << std::endl;
+      std::cerr << "Unable to open a file " << fileName << "." << std::endl;
       return false;
    }
    if( format == "vtk" )
-      return MeshFunctionVTKWriter< ThisType >::write( *this, file );
-   if( format == "gnuplot" )
-      return MeshFunctionGnuplotWriter< ThisType >::write( *this, file );
+      return MeshFunctionVTKWriter< ThisType >::write( *this, file, scale );
+   else if( format == "gnuplot" )
+      return MeshFunctionGnuplotWriter< ThisType >::write( *this, file, scale );
+   else {
+      std::cerr << "Unknown output format: " << format << std::endl;
+      return false;
+   }
    return true;
 }
  
diff --git a/src/TNL/Functions/OperatorFunction.h b/src/TNL/Functions/OperatorFunction.h
index 842383b29a7916ac33fa5c8e4dee9ef04f2b6c7f..c5dbde42363c27f2d58d53018d7efb41096b76ad 100644
--- a/src/TNL/Functions/OperatorFunction.h
+++ b/src/TNL/Functions/OperatorFunction.h
@@ -30,19 +30,21 @@ namespace Functions {
  */
    
 template< typename Operator,
-          typename MeshFunction,
+          typename Function = typename Operator::FunctionType,
           typename BoundaryConditions = void,
-          bool EvaluateOnFly = false >
+          bool EvaluateOnFly = false,
+          bool IsAnalytic = ( Function::getDomainType() == SpaceDomain || Function::getDomainType() == NonspaceDomain ) >
 class OperatorFunction{};
 
 /****
  * Specialization for 'On the fly' evaluation with the boundary conditions does not make sense.
  */
 template< typename Operator,
-          typename MeshFunction,
-          typename BoundaryConditions >
-class OperatorFunction< Operator, MeshFunction, BoundaryConditions, true >
- : public Domain< Operator::getMeshDimensions(), MeshDomain >
+          typename MeshFunctionT,
+          typename BoundaryConditions,
+          bool IsAnalytic >
+class OperatorFunction< Operator, MeshFunctionT, BoundaryConditions, true, IsAnalytic >
+ : public Domain< Operator::getDimension(), MeshDomain >
 {
 };
 
@@ -50,16 +52,17 @@ class OperatorFunction< Operator, MeshFunction, BoundaryConditions, true >
  * Specialization for 'On the fly' evaluation and no boundary conditions.
  */
 template< typename Operator,
-          typename MeshFunctionT >
-class OperatorFunction< Operator, MeshFunctionT, void, true >
- : public Domain< Operator::getDomainDimensions(), Operator::getDomainType() >
+          typename MeshFunctionT,
+          bool IsAnalytic >
+class OperatorFunction< Operator, MeshFunctionT, void, true, IsAnalytic >
+ : public Domain< Operator::getDomainDimension(), Operator::getDomainType() >
 {
    public:
  
       static_assert( MeshFunctionT::getDomainType() == MeshDomain ||
                      MeshFunctionT::getDomainType() == MeshInteriorDomain ||
                      MeshFunctionT::getDomainType() == MeshBoundaryDomain,
-         "Only mesh preimageFunctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." );
+         "Only mesh preimageFnctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." );
       static_assert( std::is_same< typename Operator::MeshType, typename MeshFunctionT::MeshType >::value,
           "Both, operator and mesh preimageFunction must be defined on the same mesh." );
  
@@ -70,10 +73,10 @@ class OperatorFunction< Operator, MeshFunctionT, void, true >
       typedef typename OperatorType::DeviceType DeviceType;
       typedef typename OperatorType::IndexType IndexType;
       typedef typename OperatorType::ExactOperatorType ExactOperatorType;
-      typedef MeshFunction< MeshType, OperatorType::getPreimageEntitiesDimensions() > PreimageFunctionType;
+      typedef MeshFunction< MeshType, OperatorType::getPreimageEntitiesDimension() > PreimageFunctionType;
       typedef SharedPointer< MeshType, DeviceType > MeshPointer;
       
-      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
+      static constexpr int getEntitiesDimension() { return OperatorType::getImageEntitiesDimension(); };     
       
       OperatorFunction( const OperatorType& operator_ )
       :  operator_( operator_ ), preimageFunction( 0 ){};
@@ -84,13 +87,13 @@ class OperatorFunction< Operator, MeshFunctionT, void, true >
  
       const MeshType& getMesh() const
       {
-         Assert( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         TNL_ASSERT_TRUE( this->preimageFunction, "The preimage function was not set." );
          return this->preimageFunction->getMesh();
       };
       
       const MeshPointer& getMeshPointer() const
       { 
-         tnlAssert( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         TNL_ASSERT_TRUE( this->preimageFunction, "The preimage function was not set." );
          return this->preimageFunction->getMeshPointer(); 
       };
 
@@ -111,7 +114,7 @@ class OperatorFunction< Operator, MeshFunctionT, void, true >
          const MeshEntity& meshEntity,
          const RealType& time = 0.0 ) const
       {
-         Assert( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         TNL_ASSERT_TRUE( this->preimageFunction, "The preimage function was not set." );
          return operator_( *preimageFunction, meshEntity, time );
       }
  
@@ -128,9 +131,10 @@ class OperatorFunction< Operator, MeshFunctionT, void, true >
  * Specialization for precomputed evaluation and no boundary conditions.
  */
 template< typename Operator,
-          typename PreimageFunction >
-class OperatorFunction< Operator, PreimageFunction, void, false >
- : public Domain< Operator::getDomainDimensions(), Operator::getDomainType() >
+          typename PreimageFunction,
+          bool IsAnalytic >
+class OperatorFunction< Operator, PreimageFunction, void, false, IsAnalytic >
+ : public Domain< Operator::getDomainDimension(), Operator::getDomainType() >
 {
    public:
  
@@ -147,12 +151,12 @@ class OperatorFunction< Operator, PreimageFunction, void, false >
       typedef typename OperatorType::DeviceType DeviceType;
       typedef typename OperatorType::IndexType IndexType;
       typedef PreimageFunction PreimageFunctionType;
-      typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimension() > ImageFunctionType;
       typedef OperatorFunction< Operator, PreimageFunction, void, true > OperatorFunctionType;
       typedef typename OperatorType::ExactOperatorType ExactOperatorType;
       typedef SharedPointer< MeshType, DeviceType > MeshPointer;
       
-      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
+      static constexpr int getEntitiesDimension() { return OperatorType::getImageEntitiesDimension(); };     
       
       OperatorFunction( OperatorType& operator_,
                            const MeshPointer& mesh )
@@ -172,7 +176,7 @@ class OperatorFunction< Operator, PreimageFunction, void, false >
  
       const ImageFunctionType& getImageFunction() const { return this->imageFunction; };
  
-      void setPreimageFunction( PreimageFunction& preimageFunction )
+      void setPreimageFunction( PreimageFunctionType& preimageFunction )
       {
          this->preimageFunction = &preimageFunction;
          this->imageFunction.setMesh( preimageFunction.getMeshPointer() );
@@ -232,18 +236,19 @@ class OperatorFunction< Operator, PreimageFunction, void, false >
  * Specialization for precomputed evaluation and with boundary conditions.
  */
 template< typename Operator,
-          typename PreimageFunction,
-          typename BoundaryConditions >
-class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
-  : public Domain< Operator::getMeshDimensions(), MeshDomain >
+          typename Function,
+          typename BoundaryConditions,
+          bool IsAnalytic >
+class OperatorFunction< Operator, Function, BoundaryConditions, false, IsAnalytic >
+  : public Domain< Operator::getDimension(), MeshDomain >
 {
    public:
  
-      static_assert( PreimageFunction::getDomainType() == MeshDomain ||
-                     PreimageFunction::getDomainType() == MeshInteriorDomain ||
-                     PreimageFunction::getDomainType() == MeshBoundaryDomain,
+      static_assert( Function::getDomainType() == MeshDomain ||
+                     Function::getDomainType() == MeshInteriorDomain ||
+                     Function::getDomainType() == MeshBoundaryDomain,
          "Only mesh preimageFunctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." );
-      static_assert( std::is_same< typename Operator::MeshType, typename PreimageFunction::MeshType >::value,
+      static_assert( std::is_same< typename Operator::MeshType, typename Function::MeshType >::value,
           "Both, operator and mesh preimageFunction must be defined on the same mesh." );
       static_assert( std::is_same< typename BoundaryConditions::MeshType, typename Operator::MeshType >::value,
          "The operator and the boundary conditions are defined on different mesh types." );
@@ -254,13 +259,13 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
       typedef typename OperatorType::RealType RealType;
       typedef typename OperatorType::DeviceType DeviceType;
       typedef typename OperatorType::IndexType IndexType;
-      typedef PreimageFunction PreimageFunctionType;
-      typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef Function PreimageFunctionType;
+      typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimension() > ImageFunctionType;
       typedef BoundaryConditions BoundaryConditionsType;
-      typedef OperatorFunction< Operator, PreimageFunction, void, true > OperatorFunctionType;
+      typedef OperatorFunction< Operator, Function, void, true > OperatorFunctionType;
       typedef typename OperatorType::ExactOperatorType ExactOperatorType;
  
-      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };
+      static constexpr int getEntitiesDimension() { return OperatorType::getImageEntitiesDimension(); };
  
       OperatorFunction( OperatorType& operator_,
                            const BoundaryConditionsType& boundaryConditions,
@@ -286,20 +291,20 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
       
       const MeshPointer& getMeshPointer() const { return imageFunction.getMeshPointer(); };
       
-      void setPreimageFunction( const PreimageFunction& preimageFunction )
+      void setPreimageFunction( const PreimageFunctionType& preimageFunction )
       {
          this->preimageFunction = &preimageFunction;
       }
  
       const PreimageFunctionType& getPreimageFunction() const
       {
-         Assert( this->preimageFunction, );
+         TNL_ASSERT_TRUE( this->preimageFunction, "The preimage function was not set." );
          return *this->preimageFunction;
       };
  
       PreimageFunctionType& getPreimageFunction()
       {
-         Assert( this->preimageFunction, );
+         TNL_ASSERT_TRUE( this->preimageFunction, "The preimage function was not set." );
          return *this->preimageFunction;
       };
  
@@ -357,6 +362,67 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
       template< typename, typename > friend class MeshFunctionEvaluator;
 };
 
+/****
+ * Specialization for precomputed evaluation and with boundary conditions.
+ */
+template< typename Operator,
+          typename Function >
+class OperatorFunction< Operator, Function, void, false, true >
+  : public Domain< Function::getDomainDimension(), Function::getDomainType() >
+{
+   public:
+      
+      typedef Function FunctionType;
+      typedef typename FunctionType::RealType RealType;
+      typedef typename FunctionType::PointType PointType;
+      typedef Operator OperatorType;
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         return( this->function.setup( parameters, prefix) &&
+                 this->operator_.setup( parameters, prefix ) );
+      }
+      
+      __cuda_callable__
+      FunctionType& getFunction()
+      {
+         return this->function;
+      }
+      
+      __cuda_callable__
+      const FunctionType& getFunction() const
+      {
+         return this->function;
+      }
+      
+      __cuda_callable__
+      OperatorType& getOperator()
+      {
+         return this->operator_;
+      }
+      
+      __cuda_callable__
+      const OperatorType& getOperator() const
+      {
+         return this->operator_;
+      }
+      
+      __cuda_callable__
+      RealType operator()( const PointType& v,
+                           const RealType& time = 0.0 ) const
+      {
+         return this->operator_( this->function, v, time );
+      }
+      
+   protected:
+      
+      Function function;
+      
+      Operator operator_;
+ 
+};
+
 } // namespace Functions
 } // namespace TNL
 
diff --git a/src/TNL/Functions/TestFunction.h b/src/TNL/Functions/TestFunction.h
index 55e50c4f9df42f064590b06a62fd8622e5ba0492..0f97ff21af51b74656afa4e9f2d554f026f20290 100644
--- a/src/TNL/Functions/TestFunction.h
+++ b/src/TNL/Functions/TestFunction.h
@@ -19,123 +19,120 @@
 namespace TNL {
 namespace Functions {   
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real = double,
           typename Device = Devices::Host >
-class TestFunction : public Domain< FunctionDimensions, SpaceDomain >
+class TestFunction : public Domain< FunctionDimension, SpaceDomain >
 {
    protected:
 
-   enum TestFunctions{ constant,
-                       expBump,
-                       sinBumps,
-                       sinWave,
-		       cylinder,
-		       flowerpot,
-		       twins,
-           pseudoSquare,
-           blob };
-
-   enum TimeDependence { none,
-                         linear,
-                         quadratic,
-                         cosine };
+      enum TestFunctions{ constant,
+                          paraboloid,
+                          expBump,
+                          sinBumps,
+                          sinWave,
+                          cylinder,
+                          flowerpot,
+                          twins,
+                          pseudoSquare,
+                          blob,
+                          vectorNorm,
+                          paraboloidSDF,
+                          sinWaveSDF,
+                          sinBumpsSDF };
+
+      enum TimeDependence { none,
+                            linear,
+                            quadratic,
+                            cosine };
+
+      enum Operators { identity,
+                       heaviside };
 
    public:
 
-   enum{ Dimensions = FunctionDimensions };
-   typedef Real RealType;
-   typedef Containers::StaticVector< Dimensions, Real > VertexType;
+      enum{ Dimension = FunctionDimension };
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimension, Real > PointType;
 
-   TestFunction();
+      TestFunction();
 
-   static void configSetup( Config::ConfigDescription& config,
-                            const String& prefix = "" );
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" );
 
-   bool setup( const Config::ParameterContainer& parameters,
-              const String& prefix = "" );
+      bool setup( const Config::ParameterContainer& parameters,
+                 const String& prefix = "" );
 
-   const TestFunction& operator = ( const TestFunction& function );
+      const TestFunction& operator = ( const TestFunction& function );
 
-#ifdef HAVE_NOT_CXX11
-   template< int XDiffOrder,
-             int YDiffOrder,
-             int ZDiffOrder >
-#else
-   template< int XDiffOrder = 0,
-             int YDiffOrder = 0,
-             int ZDiffOrder = 0 >
-#endif
-   __cuda_callable__
-   Real getPartialDerivative( const VertexType& vertex,
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      Real getPartialDerivative( const PointType& vertex,
+                                 const Real& time = 0 ) const;
+
+      __cuda_callable__
+      Real operator()( const PointType& vertex,
+                     const Real& time = 0 ) const
+      {
+         return this->getPartialDerivative< 0, 0, 0 >( vertex, time );
+      }
+
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      Real getTimeDerivative( const PointType& vertex,
                               const Real& time = 0 ) const;
 
-   __cuda_callable__
-   Real operator()( const VertexType& vertex,
-                  const Real& time = 0 ) const
-   {
-      return this->getPartialDerivative< 0, 0, 0 >( vertex, time );
-   }
-
-
-#ifdef HAVE_NOT_CXX11
-   template< int XDiffOrder,
-             int YDiffOrder,
-             int ZDiffOrder >
-#else
-   template< int XDiffOrder = 0,
-             int YDiffOrder = 0,
-             int ZDiffOrder = 0 >
-#endif
-   __cuda_callable__
-   Real getTimeDerivative( const VertexType& vertex,
-                           const Real& time = 0 ) const;
-
-#ifdef HAVE_NOT_CXX11
-   template< typename Vertex >
-   __cuda_callable__
-   Real getTimeDerivative( const Vertex& vertex,
-                           const Real& time = 0 ) const
-   {
-      return this->getTimeDerivative< 0, 0, 0, Vertex >( vertex, time );
-   }
-#endif
-
-   std::ostream& print( std::ostream& str ) const;
-
-   ~TestFunction();
+      std::ostream& print( std::ostream& str ) const;
+
+      ~TestFunction();
 
    protected:
 
-   template< typename FunctionType >
-   bool setupFunction( const Config::ParameterContainer& parameters,
-                      const String& prefix = "" );
+      template< typename FunctionType >
+      bool setupFunction( const Config::ParameterContainer& parameters,
+                         const String& prefix = "" );
+      
+      template< typename OperatorType >
+      bool setupOperator( const Config::ParameterContainer& parameters,
+                          const String& prefix = "" );
+
+      template< typename FunctionType >
+      void deleteFunction();
+
+      template< typename OperatorType >
+      void deleteOperator();
 
-   template< typename FunctionType >
-   void deleteFunction();
+      void deleteFunctions();
 
-   void deleteFunctions();
+      template< typename FunctionType >
+      void copyFunction( const void* function );
 
-   template< typename FunctionType >
-   void copyFunction( const void* function );
+      template< typename FunctionType >
+      std::ostream& printFunction( std::ostream& str ) const;
 
-   template< typename FunctionType >
-   std::ostream& printFunction( std::ostream& str ) const;
+      void* function;
 
-   void* function;
+      void* operator_;
 
-   TestFunctions functionType;
+      TestFunctions functionType;
+      
+      Operators operatorType;
 
-   TimeDependence timeDependence;
+      TimeDependence timeDependence;
 
-   Real timeScale;
+      Real timeScale;
 
 };
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
-std::ostream& operator << ( std::ostream& str, const TestFunction< FunctionDimensions, Real, Device >& f )
+std::ostream& operator << ( std::ostream& str, const TestFunction< FunctionDimension, Real, Device >& f )
 {
    str << "Test function: ";
    return f.print( str );
diff --git a/src/TNL/Functions/TestFunction_impl.h b/src/TNL/Functions/TestFunction_impl.h
index 35713a8944099edbef223c4017ade5cba749203d..34ae43529b92cadb3f23ca4f57176255c9d09d45 100644
--- a/src/TNL/Functions/TestFunction_impl.h
+++ b/src/TNL/Functions/TestFunction_impl.h
@@ -24,31 +24,44 @@
 #include <TNL/Functions/Analytic/Twins.h>
 #include <TNL/Functions/Analytic/Blob.h>
 #include <TNL/Functions/Analytic/PseudoSquare.h>
+#include <TNL/Functions/Analytic/Paraboloid.h>
+#include <TNL/Functions/Analytic/VectorNorm.h>
+/****
+ * The signed distance test functions
+ */
+#include <TNL/Functions/Analytic/SinBumpsSDF.h>
+#include <TNL/Functions/Analytic/SinWaveSDF.h>
+#include <TNL/Functions/Analytic/ParaboloidSDF.h>
+
+#include <TNL/Operators/Analytic/Identity.h>
+#include <TNL/Operators/Analytic/Heaviside.h>
 
 namespace TNL {
 namespace Functions {   
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 TestFunction()
 : function( 0 ),
+  operator_( 0 ),
   timeDependence( none ),
   timeScale( 1.0 )
 {
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
 void
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
    config.addRequiredEntry< String >( prefix + "test-function", "Testing function." );
       config.addEntryEnum( "constant" );
+      config.addEntryEnum( "paraboloid" );
       config.addEntryEnum( "exp-bump" );
       config.addEntryEnum( "sin-wave" );
       config.addEntryEnum( "sin-bumps" );
@@ -57,6 +70,11 @@ configSetup( Config::ConfigDescription& config,
       config.addEntryEnum( "twins" );
       config.addEntryEnum( "pseudoSquare" );
       config.addEntryEnum( "blob" );
+      config.addEntryEnum( "paraboloid-sdf" );      
+      config.addEntryEnum( "sin-wave-sdf" );
+      config.addEntryEnum( "sin-bumps-sdf" );
+      config.addEntryEnum( "heaviside-of-vector-norm" );
+
    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 );
@@ -72,8 +90,14 @@ configSetup( Config::ConfigDescription& 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 + "radius", "Radius for paraboloids.", 1.0 );
+   config.addEntry     < double >( prefix + "coefficient", "Coefficient for paraboloids.", 1.0 );
+   config.addEntry     < double >( prefix + "x-center", "x-center for paraboloids.", 0.0 );
+   config.addEntry     < double >( prefix + "y-center", "y-center for paraboloids.", 0.0 );
+   config.addEntry     < double >( prefix + "z-center", "z-center 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 );
+   Analytic::VectorNorm< 3, double >::configSetup( config, "vector-norm-" );
    config.addEntry     < String >( prefix + "time-dependence", "Time dependence of the test function.", "none" );
       config.addEntryEnum( "none" );
       config.addEntryEnum( "linear" );
@@ -83,12 +107,12 @@ configSetup( Config::ConfigDescription& config,
 
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< typename FunctionType >
 bool
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 setupFunction( const Config::ParameterContainer& parameters,
                const String& prefix )
 {
@@ -107,21 +131,52 @@ setupFunction( const Config::ParameterContainer& parameters,
    {
       this->function = Devices::Cuda::passToDevice( *auxFunction );
       delete auxFunction;
-      if( ! checkCudaDevice )
+      if( ! TNL_CHECK_CUDA_DEVICE )
+         return false;
+   }
+   return true;
+}
+
+template< int FunctionDimension,
+          typename Real,
+          typename Device >
+   template< typename OperatorType >
+bool
+TestFunction< FunctionDimension, Real, Device >::
+setupOperator( const Config::ParameterContainer& parameters,
+               const String& prefix )
+{
+   OperatorType* auxOperator = new OperatorType;
+   if( ! auxOperator->setup( parameters, prefix ) )
+   {
+      delete auxOperator;
+      return false;
+   }
+
+   if( std::is_same< Device, Devices::Host >::value )
+   {
+      this->operator_ = auxOperator;
+   }
+   if( std::is_same< Device, Devices::Cuda >::value )
+   {
+      this->operator_ = Devices::Cuda::passToDevice( *auxOperator );
+      delete auxOperator;
+      if( ! TNL_CHECK_CUDA_DEVICE )
          return false;
    }
    return true;
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
 bool
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
    using namespace TNL::Functions::Analytic;
+   using namespace TNL::Operators::Analytic;
    std::cout << "Test function setup ... " << std::endl;
    const String& timeDependence =
             parameters.getParameter< String >(
@@ -140,70 +195,151 @@ setup( const Config::ParameterContainer& parameters,
    this->timeScale = parameters.getParameter< double >( prefix + "time-scale" );
 
    const String& testFunction = parameters.getParameter< String >( prefix + "test-function" );
-  std::cout << "Test function ... " << testFunction << std::endl;
+   std::cout << "Test function ... " << testFunction << std::endl;
    if( testFunction == "constant" )
    {
-      typedef Constant< Dimensions, Real > FunctionType;
+      typedef Constant< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = constant;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
+   if( testFunction == "paraboloid" )
+   {
+      typedef Paraboloid< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
+      functionType = paraboloid;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }   
    if( testFunction == "exp-bump" )
    {
-      typedef ExpBump< Dimensions, Real > FunctionType;
+      typedef ExpBump< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = expBump;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "sin-bumps" )
    {
-      typedef SinBumps< Dimensions, Real > FunctionType;
+      typedef SinBumps< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = sinBumps;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "sin-wave" )
    {
-      typedef SinWave< Dimensions, Real > FunctionType;
+      typedef SinWave< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = sinWave;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "cylinder" )
    {
-      typedef Cylinder< Dimensions, Real > FunctionType;
+      typedef Cylinder< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = cylinder;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "flowerpot" )
    {
-      typedef Flowerpot< Dimensions, Real > FunctionType;
+      typedef Flowerpot< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = flowerpot;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "twins" )
    {
-      typedef Twins< Dimensions, Real > FunctionType;
+      typedef Twins< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = twins;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "pseudoSquare" )
    {
-      typedef PseudoSquare< Dimensions, Real > FunctionType;
+      typedef PseudoSquare< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = pseudoSquare;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    if( testFunction == "blob" )
    {
-      typedef Blob< Dimensions, Real > FunctionType;
+      typedef Blob< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
       functionType = blob;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }
+   if( testFunction == "paraboloid-sdf" )
+   {
+      typedef ParaboloidSDF< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
+      functionType = paraboloidSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }   
+   if( testFunction == "sin-bumps-sdf" )
+   {
+      typedef SinBumpsSDF< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
+      functionType = sinBumpsSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }   
+   if( testFunction == "sin-wave-sdf" )
+   {
+      typedef SinWaveSDF< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
+      functionType = sinWaveSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }
+   if( testFunction == "vector-norm" )
+   {
+      typedef VectorNorm< Dimension, Real > FunctionType;
+      typedef Identity< Dimension, Real > OperatorType;
+      functionType = vectorNorm;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }
+   if( testFunction == "heaviside-of-vector-norm" )
+   {
+      typedef VectorNorm< Dimension, Real > FunctionType;
+      typedef Heaviside< Dimension, Real > OperatorType;
+      functionType = vectorNorm;
+      operatorType = heaviside;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    std::cerr << "Unknown function " << testFunction << std::endl;
    return false;
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
-const TestFunction< FunctionDimensions, Real, Device >&
-TestFunction< FunctionDimensions, Real, Device >::
+const TestFunction< FunctionDimension, Real, Device >&
+TestFunction< FunctionDimension, Real, Device >::
 operator = ( const TestFunction& function )
 {
    /*****
@@ -220,40 +356,49 @@ operator = ( const TestFunction& function )
    switch( this->functionType )
    {
       case constant:
-         this->copyFunction< Constant< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< Constant< FunctionDimension, Real > >( function.function );
          break;
       case expBump:
-         this->copyFunction< ExpBump< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< ExpBump< FunctionDimension, Real > >( function.function );
          break;
       case sinBumps:
-         this->copyFunction< SinBumps< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< SinBumps< FunctionDimension, Real > >( function.function );
          break;
       case sinWave:
-         this->copyFunction< SinWave< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< SinWave< FunctionDimension, Real > >( function.function );
          break;
       case cylinder:
-         this->copyFunction< Cylinder< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< Cylinder< FunctionDimension, Real > >( function.function );
          break;
       case flowerpot:
-         this->copyFunction< Flowerpot< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< Flowerpot< FunctionDimension, Real > >( function.function );
          break;
       case twins:
-         this->copyFunction< Twins< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< Twins< FunctionDimension, Real > >( function.function );
          break;
       case pseudoSquare:
-         this->copyFunction< PseudoSquare< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< PseudoSquare< FunctionDimension, Real > >( function.function );
          break;
       case blob:
-         this->copyFunction< Blob< FunctionDimensions, Real > >( function.function );
+         this->copyFunction< Blob< FunctionDimension, Real > >( function.function );
+         break;
+
+      case paraboloidSDF:
+         this->copyFunction< Paraboloid< FunctionDimension, Real > >( function.function );
+         break;
+      case sinBumpsSDF:
+         this->copyFunction< SinBumpsSDF< FunctionDimension, Real > >( function.function );
+         break;
+      case sinWaveSDF:
+         this->copyFunction< SinWaveSDF< FunctionDimension, Real > >( function.function );
          break;
       default:
-         Assert( false, );
+         TNL_ASSERT( false, );
          break;
    }
-
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< int XDiffOrder,
@@ -261,11 +406,12 @@ template< int FunctionDimensions,
              int ZDiffOrder >
 __cuda_callable__
 Real
-TestFunction< FunctionDimensions, Real, Device >::
-getPartialDerivative( const VertexType& vertex,
+TestFunction< FunctionDimension, Real, Device >::
+getPartialDerivative( const PointType& vertex,
           const Real& time ) const
 {
    using namespace TNL::Functions::Analytic;
+   using namespace TNL::Operators::Analytic;
    Real scale( 1.0 );
    switch( this->timeDependence )
    {
@@ -286,38 +432,144 @@ getPartialDerivative( const VertexType& vertex,
    switch( functionType )
    {
       case constant:
-         return scale * ( ( Constant< Dimensions, Real >* ) function )->
-                   template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Constant< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimension, Real > FunctionType;
+         if( operatorType == identity )
+         {
+            typedef Identity< Dimension, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+         if( operatorType == heaviside )
+         {
+            typedef Heaviside< Dimension, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+      }
       case expBump:
-         return scale * ( ( ExpBump< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef ExpBump< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case sinBumps:
-         return scale * ( ( SinBumps< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef SinBumps< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case sinWave:
-         return scale * ( ( SinWave< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef SinWave< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case cylinder:
-         return scale * ( ( Cylinder< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Cylinder< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case flowerpot:
-         return scale * ( ( Flowerpot< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Flowerpot< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case twins:
-         return scale * ( ( Twins< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Twins< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case pseudoSquare:
-         return scale * ( ( PseudoSquare< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef PseudoSquare< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
       case blob:
-         return scale * ( ( Blob< Dimensions, Real >* ) function )->
-                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Blob< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case vectorNorm:
+      {
+         typedef VectorNorm< Dimension, Real > FunctionType;
+         if( operatorType == identity )
+         {
+            typedef Identity< Dimension, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+         if( operatorType == heaviside )
+         {
+            typedef Heaviside< Dimension, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+      }      
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+                  
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimension, Real > FunctionType;
+         typedef Identity< Dimension, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      
       default:
          return 0.0;
    }
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< int XDiffOrder,
@@ -325,8 +577,8 @@ template< int FunctionDimensions,
              int ZDiffOrder >
 __cuda_callable__
 Real
-TestFunction< FunctionDimensions, Real, Device >::
-getTimeDerivative( const VertexType& vertex,
+TestFunction< FunctionDimension, Real, Device >::
+getTimeDerivative( const PointType& vertex,
                    const Real& time ) const
 {
    using namespace TNL::Functions::Analytic;
@@ -348,49 +600,102 @@ getTimeDerivative( const VertexType& vertex,
    switch( functionType )
    {
       case constant:
-         return scale * ( ( Constant< Dimensions, Real >* ) function )->
+      {
+         typedef Constant< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case expBump:
-         return scale * ( ( ExpBump< Dimensions, Real >* ) function )->
+      {
+         typedef ExpBump< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case sinBumps:
-         return scale * ( ( SinBumps< Dimensions, Real >* ) function )->
+      {
+         typedef SinBumps< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case sinWave:
-         return scale * ( ( SinWave< Dimensions, Real >* ) function )->
+      {
+         typedef SinWave< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case cylinder:
-         return scale * ( ( Cylinder< Dimensions, Real >* ) function )->
+      {
+         typedef Cylinder< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case flowerpot:
-         return scale * ( ( Flowerpot< Dimensions, Real >* ) function )->
+      {
+         typedef Flowerpot< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case twins:
-         return scale * ( ( Twins< Dimensions, Real >* ) function )->
+      {
+         typedef Twins< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case pseudoSquare:
-         return scale * ( ( PseudoSquare< Dimensions, Real >* ) function )->
+      {
+         typedef PseudoSquare< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case blob:
-         return scale * ( ( Blob< Dimensions, Real >* ) function )->
+      {
+         typedef Blob< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
+
+
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimension, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->template
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       default:
          return 0.0;
    }
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< typename FunctionType >
 void
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 deleteFunction()
 {
    if( std::is_same< Device, Devices::Host >::value )
@@ -405,52 +710,149 @@ deleteFunction()
    }
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
+   template< typename OperatorType >
 void
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
+deleteOperator()
+{
+   if( std::is_same< Device, Devices::Host >::value )
+   {
+      if( operator_ )
+         delete ( OperatorType * ) operator_;
+   }
+   if( std::is_same< Device, Devices::Cuda >::value )
+   {
+      if( operator_ )
+         Devices::Cuda::freeFromDevice( ( OperatorType * ) operator_ );
+   }
+}
+
+template< int FunctionDimension,
+          typename Real,
+          typename Device >
+void
+TestFunction< FunctionDimension, Real, Device >::
 deleteFunctions()
 {
    using namespace TNL::Functions::Analytic;
+   using namespace TNL::Operators::Analytic;
    switch( functionType )
    {
       case constant:
-         deleteFunction< Constant< Dimensions, Real> >();
-         break;
+      {
+         typedef Constant< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         if( operatorType == identity )
+            deleteOperator< Identity< Dimension, Real > >();
+         if( operatorType == heaviside )
+            deleteOperator< Heaviside< Dimension, Real > >();
+         break;
+      }
       case expBump:
-         deleteFunction< ExpBump< Dimensions, Real> >();
+      {
+         typedef ExpBump< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case sinBumps:
-         deleteFunction< SinBumps< Dimensions, Real> >();
+      {
+         typedef SinBumps< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case sinWave:
-         deleteFunction< SinWave< Dimensions, Real> >();
+      {
+         typedef SinWave< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case cylinder:
-         deleteFunction< Cylinder< Dimensions, Real> >();
+      {
+         typedef Cylinder< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case flowerpot:
-         deleteFunction< Flowerpot< Dimensions, Real> >();
+      {
+         typedef Flowerpot< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case twins:
-         deleteFunction< Twins< Dimensions, Real> >();
+      {
+         typedef Twins< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case pseudoSquare:
-         deleteFunction< PseudoSquare< Dimensions, Real> >();
+      {
+         typedef PseudoSquare< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
          break;
+      }
       case blob:
-         deleteFunction< Blob< Dimensions, Real> >();
-         break;
+      {
+         typedef Blob< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
+      case vectorNorm:
+      {
+         typedef VectorNorm< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
+      
+      
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimension, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimension, Real > >();
+         break;
+      }
    }
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< typename FunctionType >
 void
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 copyFunction( const void* function )
 {
    if( std::is_same< Device, Devices::Host >::value )
@@ -460,17 +862,17 @@ copyFunction( const void* function )
    }
    if( std::is_same< Device, Devices::Cuda >::value )
    {
-      Assert( false, );
+      TNL_ASSERT( false, );
       abort();
    }
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
    template< typename FunctionType >
 std::ostream&
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 printFunction( std::ostream& str ) const
 {
    FunctionType* f = ( FunctionType* ) this->function;
@@ -484,14 +886,13 @@ printFunction( std::ostream& str ) const
       Devices::Cuda::print( f, str );
       return str;
    }
-   return str;
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
 std::ostream&
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 print( std::ostream& str ) const
 {
    using namespace TNL::Functions::Analytic;
@@ -501,31 +902,31 @@ print( std::ostream& str ) const
    switch( functionType )
    {
       case constant:
-         return printFunction< Constant< Dimensions, Real> >( str );
+         return printFunction< Constant< Dimension, Real> >( str );
       case expBump:
-         return printFunction< ExpBump< Dimensions, Real> >( str );
+         return printFunction< ExpBump< Dimension, Real> >( str );
       case sinBumps:
-         return printFunction< SinBumps< Dimensions, Real> >( str );
+         return printFunction< SinBumps< Dimension, Real> >( str );
       case sinWave:
-         return printFunction< SinWave< Dimensions, Real> >( str );
+         return printFunction< SinWave< Dimension, Real> >( str );
       case cylinder:
-         return printFunction< Cylinder< Dimensions, Real> >( str );
+         return printFunction< Cylinder< Dimension, Real> >( str );
       case flowerpot:
-         return printFunction< Flowerpot< Dimensions, Real> >( str );
+         return printFunction< Flowerpot< Dimension, Real> >( str );
       case twins:
-         return printFunction< Twins< Dimensions, Real> >( str );
+         return printFunction< Twins< Dimension, Real> >( str );
       case pseudoSquare:
-         return printFunction< PseudoSquare< Dimensions, Real> >( str );
+         return printFunction< PseudoSquare< Dimension, Real> >( str );
       case blob:
-         return printFunction< Blob< Dimensions, Real> >( str );
+         return printFunction< Blob< Dimension, Real> >( str );
    }
    return str;
 }
 
-template< int FunctionDimensions,
+template< int FunctionDimension,
           typename Real,
           typename Device >
-TestFunction< FunctionDimensions, Real, Device >::
+TestFunction< FunctionDimension, Real, Device >::
 ~TestFunction()
 {
    deleteFunctions();
diff --git a/src/TNL/Functions/VectorField.h b/src/TNL/Functions/VectorField.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fe085e750c931d5d81cd1dbdf2c49fd9af38ad9
--- /dev/null
+++ b/src/TNL/Functions/VectorField.h
@@ -0,0 +1,280 @@
+/***************************************************************************
+                          VectorField.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Functions/MeshFunction.h>
+#include <TNL/Functions/VectorFieldGnuplotWriter.h>
+
+namespace TNL {
+namespace Functions {
+
+template< int Size,
+          typename Function >
+class VectorField 
+   : public Functions::Domain< Function::getDomainDimension(), 
+                               Function::getDomainType() >
+{
+   public:
+      
+      typedef Function FunctionType;
+      typedef typename FunctionType::RealType RealType;
+      typedef typename FunctionType::PointType PointType;
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         for( int i = 0; i < Size; i++ )
+            FunctionType::configSetup( config, prefix + String( i ) + "-" );
+      }
+
+      template< typename MeshPointer >
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         for( int i = 0; i < Size; i++ )
+            if( ! vectorField[ i ].setup( parameters, prefix + String( i ) + "-" ) )
+            {
+               std::cerr << "Unable to setup " << i << "-th coordinate of the vector field." << std::endl;
+               return false;
+            }
+         return true;
+      }
+
+      __cuda_callable__ 
+      const FunctionType& operator[]( int i ) const
+      {
+         return this->vectorField[ i ];
+      }
+      
+      __cuda_callable__ 
+      FunctionType& operator[]( int i )
+      {
+         return this->vectorField[ i ];
+      }
+
+   protected:
+      
+      Containers::StaticArray< Size, FunctionType > vectorField;
+};
+   
+   
+template< int Size,
+          typename Mesh,
+          int MeshEntityDimension,
+          typename Real >
+class VectorField< Size, MeshFunction< Mesh, MeshEntityDimension, Real > >
+: public Functions::Domain< MeshFunction< Mesh, MeshEntityDimension, Real >::getDomainDimension(), 
+                            MeshFunction< Mesh, MeshEntityDimension, Real >::getDomainType() >,
+   public Object
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef SharedPointer< MeshType > MeshPointer;
+      typedef MeshFunction< MeshType, MeshEntityDimension, RealType > FunctionType;
+      typedef SharedPointer< FunctionType > FunctionPointer;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef VectorField< Size, MeshFunction< Mesh, MeshEntityDimension, RealType > > ThisType;
+      typedef Containers::StaticVector< Size, RealType > VectorType;
+
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         for( int i = 0; i < Size; i++ )
+            FunctionType::configSetup( config, prefix + String( i ) + "-" );
+      }
+      
+      VectorField() {};
+      
+      VectorField( const MeshPointer& meshPointer )
+      {
+         for( int i = 0; i < Size; i++ )
+            this->vectorField[ i ]->setMesh( meshPointer );
+      };
+      
+      static String getType()
+      {
+         return String( "Functions::VectorField< " ) +
+                  String( Size) + ", " +
+                 FunctionType::getType() +
+                  " >";
+      }
+ 
+      String getTypeVirtual() const
+      {
+         return this->getType();
+      }
+ 
+      static String getSerializationType()
+      {
+         return String( "Functions::VectorField< " ) +
+                  String( Size) + ", " +
+                 FunctionType::getSerializationType() +
+                  " >";         
+      }
+
+      virtual String getSerializationTypeVirtual() const
+      {
+         return this->getSerializationType();
+      }
+      
+      
+      void setMesh( const MeshPointer& meshPointer )
+      {
+         for( int i = 0; i < Size; i++ )
+            this->vectorField[ i ]->setMesh( meshPointer );
+      }
+      
+      template< typename Device = Devices::Host >
+      __cuda_callable__
+      const MeshType& getMesh() const
+      {
+         return this->vectorField[ 0 ].template getData< Device >().template getMesh< Device >();
+      }
+
+      
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         for( int i = 0; i < Size; i++ )
+            if( ! vectorField[ i ].setup( meshPointer, parameters, prefix + String( i ) + "-" ) )
+            {
+               std::cerr << "Unable to setup " << i << "-th coordinate of the vector field." << std::endl;
+               return false;
+            }
+         return true;
+      }
+      
+      static IndexType getDofs( const MeshPointer& meshPointer )
+      {
+         return Size * FunctionType::getDofs( meshPointer );
+      }
+
+      __cuda_callable__ 
+      const FunctionPointer& operator[]( int i ) const
+      {
+         return this->vectorField[ i ];
+      }
+      
+      __cuda_callable__ 
+      FunctionPointer& operator[]( int i )
+      {
+         return this->vectorField[ i ];
+      }
+      
+      __cuda_callable__
+      VectorType getVector( const IndexType index ) const
+      {
+         VectorType v;
+         for( int i = 0; i < Size; i++ )
+            // FIXME: the dereferencing operator of FunctionPointer is not __cuda_callable__
+            v[ i ] = ( *this->vectorField[ i ] )[ index ];
+         return v;
+      }
+
+      template< typename EntityType >
+      __cuda_callable__
+      VectorType getVector( const EntityType& meshEntity ) const
+      {
+         VectorType v;
+         for( int i = 0; i < Size; i++ )
+            // FIXME: the dereferencing operator of FunctionPointer is not __cuda_callable__
+            v[ i ] = ( *this->vectorField[ i ] )( meshEntity );
+         return v;
+      }
+      
+      bool save( File& file ) const
+      {
+         if( ! Object::save( file ) )
+            return false;
+         for( int i = 0; i < Size; i++ )
+            if( ! vectorField[ i ]->save( file ) )
+               return false;
+         return true;
+      }
+
+      bool load( File& file )
+      {
+         if( ! Object::load( file ) )
+            return false;
+         for( int i = 0; i < Size; i++ )
+            if( ! vectorField[ i ]->load( file ) )
+               return false;
+         return true;
+      }
+ 
+      bool boundLoad( File& file )
+      {
+         if( ! Object::load( file ) )
+            return false;
+         for( int i = 0; i < Size; i++ )
+            if( ! vectorField[ i ]->boundLoad( file ) )
+               return false;
+         return true;         
+      }
+      
+      bool write( const String& fileName,
+                  const String& format = "vtk",
+                  const double& scale = 1.0 ) const
+      {
+         std::fstream file;
+         file.open( fileName.getString(), std::ios::out );
+         if( ! file )
+         {
+            std::cerr << "Unable to open a file " << fileName << "." << std::endl;
+            return false;
+         }
+         if( format == "vtk" )
+            return false; //MeshFunctionVTKWriter< ThisType >::write( *this, file );
+         else if( format == "gnuplot" )
+            return VectorFieldGnuplotWriter< ThisType >::write( *this, file, scale );
+         else {
+            std::cerr << "Unknown output format: " << format << std::endl;
+            return false;
+         }
+         return true;
+      }
+      
+      using Object::save;
+ 
+      using Object::load;
+ 
+      using Object::boundLoad;      
+
+   protected:
+      
+      Containers::StaticArray< Size, FunctionPointer > vectorField;
+   
+};
+
+template< int Dimension,
+          typename Function >
+std::ostream& operator << ( std::ostream& str, const VectorField< Dimension, Function >& f )
+{
+   for( int i = 0; i < Dimension; i++ )
+   {
+      str << "[ " << f[ i ] << " ]";
+      if( i < Dimension - 1 )
+         str << ", ";
+   }
+   return str;
+}
+
+   
+} //namespace Functions
+} //namepsace TNL
diff --git a/src/TNL/Functions/VectorFieldGnuplotWriter.h b/src/TNL/Functions/VectorFieldGnuplotWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..41b59d511d680568d62ed545a8f230efc43dd575
--- /dev/null
+++ b/src/TNL/Functions/VectorFieldGnuplotWriter.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+                          VectorFieldGnuplotWriter.h  -  description
+                             -------------------
+    begin                : Feb 16, 2017
+    copyright            : (C) 2017 by oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Meshes/Grid.h>
+
+namespace TNL {
+namespace Functions {
+
+template< int, typename > class VectorField;
+
+template< typename VectorField >
+class VectorFieldGnuplotWriter
+{
+   public:
+
+      static bool write( const VectorField& function,
+                         std::ostream& str,
+                         const double& scale );
+};
+
+/***
+ * 1D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 1, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+/***
+ * 1D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+
+/***
+ * 2D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 2, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+/***
+ * 2D grids faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 1, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+/***
+ * 2D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+
+/***
+ * 3D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 3, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+/***
+ * 3D grids faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 2, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+/***
+ * 3D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > > >
+{
+   public:
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType;
+
+      static bool write( const VectorFieldType& function,
+                         std::ostream& str,
+                         const double& scale  );
+};
+
+} // namespace Functions
+} // namespace TNL
+
+#include <TNL/Functions/VectorFieldGnuplotWriter_impl.h>
diff --git a/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h b/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..500bdc4d8fbb0d3ece8c94ec6938c4c81a51b1c8
--- /dev/null
+++ b/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h
@@ -0,0 +1,394 @@
+/***************************************************************************
+                          VectorFieldGnuplotWriter.h  -  description
+                             -------------------
+    begin                : Feb 16, 2017
+    copyright            : (C) 2017 by oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <iostream>
+#include <TNL/Functions/VectorFieldGnuplotWriter.h>
+
+namespace TNL {
+namespace Functions {
+
+template< typename VectorField >
+bool
+VectorFieldGnuplotWriter< VectorField >::
+write( const VectorField& vectorField,
+       std::ostream& str,
+       const double& scale  )
+{
+   std::cerr << "Gnuplot writer for mesh vectorFields defined on mesh type " << VectorField::MeshType::getType() << " is not (yet) implemented." << std::endl;
+   return false;
+}
+
+/****
+ * 1D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() < mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      typename MeshType::PointType v = entity.getCenter();
+      str << v.x();
+      for( int i = 0; i < VectorFieldSize; i++ )
+          str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+      str << std::endl;
+   }
+   return true;
+}
+
+/****
+ * 1D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() <= mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      typename MeshType::PointType v = entity.getCenter();
+      str << v.x();
+      for( int i = 0; i < VectorFieldSize; i++ )
+          str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+      str << std::endl;
+   }
+   return true;
+}
+
+
+/****
+ * 2D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() < mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::PointType v = entity.getCenter();
+         str << v.x() << " " << v.y();
+         for( int i = 0; i < VectorFieldSize; i++ )
+             str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+         str << std::endl;
+      }
+      str << std::endl;
+   }
+   return true;
+}
+
+/****
+ * 2D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   typedef typename MeshType::Face EntityType;
+   typedef typename EntityType::EntityOrientationType EntityOrientation;
+   EntityType entity( mesh );
+
+   entity.setOrientation( EntityOrientation( 1.0, 0.0 ) );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() < mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() <= mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::PointType v = entity.getCenter();
+         str << v.x() << " " << v.y();
+         for( int i = 0; i < VectorFieldSize; i++ )
+             str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+         str << std::endl;
+      }
+      str << std::endl;
+   }
+
+   entity.setOrientation( EntityOrientation( 0.0, 1.0 ) );
+         for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+
+   {
+            for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() <= mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )
+
+      {
+         entity.refresh();
+         typename MeshType::PointType v = entity.getCenter();
+         str << v.x() << " " << v.y();
+         for( int i = 0; i < VectorFieldSize; i++ )
+             str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+         str << std::endl;
+      }
+      str << std::endl;
+   }
+   return true;
+}
+
+
+/****
+ * 2D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() <= mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() <= mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::PointType v = entity.getCenter();
+         str << v.x() << " " << v.y();
+         for( int i = 0; i < VectorFieldSize; i++ )
+             str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+         str << std::endl;
+      }
+      str << std::endl;
+   }
+   return true;
+}
+
+
+/****
+ * 3D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z();
+            for( int i = 0; i < VectorFieldSize; i++ )
+                str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+            str << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
+/****
+ * 3D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z();
+            for( int i = 0; i < VectorFieldSize; i++ )
+                str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+            str << std::endl;
+         }
+         str << 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().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         for( entity.getCoordinates().y() = 0;
+              entity.getCoordinates().y() <= mesh.getDimensions().y();
+              entity.getCoordinates().y() ++ )
+         {
+            entity.refresh();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z();
+            for( int i = 0; i < VectorFieldSize; i++ )
+                str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+            str << std::endl;
+         }
+         str << std::endl;
+      }
+
+   entity.setOrientation( EntityOrientation( 0.0, 0.0, 1.0 ) );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() < mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+      for( entity.getCoordinates().y() = 0;
+           entity.getCoordinates().y() <= mesh.getDimensions().y();
+           entity.getCoordinates().y() ++ )
+      {
+         for( entity.getCoordinates().z() = 0;
+              entity.getCoordinates().z() < mesh.getDimensions().z();
+              entity.getCoordinates().z() ++ )
+         {
+            entity.refresh();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z();
+            for( int i = 0; i < VectorFieldSize; i++ )
+                str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+            str << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
+
+/****
+ * 3D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          int VectorFieldSize >
+bool
+VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > > >::
+write( const VectorFieldType& vectorField,
+       std::ostream& str,
+       const double& scale )
+{
+   const MeshType& mesh = vectorField.getMesh();
+   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();
+            typename MeshType::PointType v = entity.getCenter();
+            str << v.x() << " " << v.y() << " " << v.z();
+            for( int i = 0; i < VectorFieldSize; i++ )
+                str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() );
+            str << std::endl;
+         }
+         str << std::endl;
+      }
+   return true;
+}
+
+} // namespace Functions
+} // namespace TNL
+
diff --git a/src/TNL/Images/DicomSeries.h b/src/TNL/Images/DicomSeries.h
index 1350cf4a280b7ba0ad89149f818a5476f29a98e1..b3ee1fb11c88f221512e6c27071f60fbdafddbc8 100644
--- a/src/TNL/Images/DicomSeries.h
+++ b/src/TNL/Images/DicomSeries.h
@@ -15,7 +15,7 @@
 #pragma once
 
 #include <TNL/Containers/Array.h>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/String.h>
 #include <TNL/param-types.h>
 #include <TNL/Images//Image.h>
@@ -106,7 +106,7 @@ class DicomSeries : public Image< int >
  
       bool loadImage( const String& filePath, int number );
 
-      List< String > fileList;
+      Containers::List< String > fileList;
  
       Containers::Array<DicomHeader *,Devices::Host,int> dicomSeriesHeaders;
 
diff --git a/src/TNL/Images/DicomSeries_impl.h b/src/TNL/Images/DicomSeries_impl.h
index 5d0abfea4a386dd4fcb6b5fc1590ced960b56955..e9a3f064c78925c2dc333e43f56a50d8a86f0c4a 100644
--- a/src/TNL/Images/DicomSeries_impl.h
+++ b/src/TNL/Images/DicomSeries_impl.h
@@ -155,7 +155,7 @@ inline bool DicomSeries::retrieveFileList( const String& filePath)
       String fileNamePrefix(fileName.getString(), 0, fileName.getLength() - separatorPosition);
 
       struct dirent **dirp;
-      List<String > files;
+      Containers::List<String > files;
 
       //scan and sort directory
       int ndirs = scandir(directoryPath.getString(), &dirp, filter, alphasort);
diff --git a/src/TNL/Images/PGMImage_impl.h b/src/TNL/Images/PGMImage_impl.h
index eb6d59d3c15a54993a83d277880703f6b3d3371e..8939dd71d1156a7eabd030266fd5d57519fcc31d 100644
--- a/src/TNL/Images/PGMImage_impl.h
+++ b/src/TNL/Images/PGMImage_impl.h
@@ -186,16 +186,15 @@ write( const Meshes::Grid< 2, Real, Device, Index >& grid,
 
          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;
-      }
- 
+         {
+             int color_aux = (int)color;
+             this->file << color_aux;
+                  this->file << ' ';
+         }
+         else this->file << color;
+      }      
       if ( ! this->binary )
-        this->file << '\n';
+         this->file << '\n';
    }
    return true;
 }
diff --git a/src/TNL/Images/RegionOfInterest_impl.h b/src/TNL/Images/RegionOfInterest_impl.h
index 387b6fb341dda9267c010aa8c8275fb0a89d5b65..e8469670b7e6e060a40be70c540a763f021322b5 100644
--- a/src/TNL/Images/RegionOfInterest_impl.h
+++ b/src/TNL/Images/RegionOfInterest_impl.h
@@ -163,7 +163,7 @@ setGrid( Grid& grid,
          bool verbose )
 {
     grid.setDimensions( this->getWidth(), this->getHeight() );
-    typename Grid::VertexType origin, proportions;
+    typename Grid::PointType origin, proportions;
     origin.x() = 0.0;
     origin.y() = 0.0;
     proportions.x() = 1.0;
diff --git a/src/TNL/Logger.cpp b/src/TNL/Logger.cpp
index fdded84ad5dc5798caaf0bed5ba41ec0e62804e2..6287cc3b3337c8ec78ca4039e404e8a316f192f2 100644
--- a/src/TNL/Logger.cpp
+++ b/src/TNL/Logger.cpp
@@ -10,8 +10,7 @@
 
 #include <iomanip>
 #include <TNL/Logger.h>
-#include <TNL/tnlConfig.h>
-#include <TNL/SystemInfo.h>
+#include <TNL/Devices/Host.h>
 #include <TNL/Devices/CudaDeviceInfo.h>
 
 namespace TNL {
@@ -45,90 +44,41 @@ void Logger :: writeSeparator()
 
 bool Logger :: writeSystemInformation( const Config::ParameterContainer& parameters )
 {
-   SystemInfo systemInfo;
-
-
-   writeParameter< String >( "Host name:", systemInfo.getHostname() );
-   writeParameter< String >( "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< String >( "CPU info", String("") );
-   writeParameter< String >( "Model name:", systemInfo.getCPUModelName( cpu_id ), 1 );
-   writeParameter< int >( "Cores:", cores, 1 );
-   writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
-   writeParameter< String >( "Max clock rate (in MHz):", systemInfo.getCPUMaxFrequency( cpu_id ) / 1000, 1 );
-   tnlCacheSizes cacheSizes = systemInfo.getCPUCacheSizes( cpu_id );
-   String cacheInfo = String( cacheSizes.L1data ) + ", "
-                       + String( cacheSizes.L1instruction ) + ", "
-                       + String( cacheSizes.L2 ) + ", "
-                       + String( cacheSizes.L3 );
-   writeParameter< String >( "Cache (L1d, L1i, L2, L3):", cacheInfo, 1 );
+   Devices::Host::writeDeviceInfo( *this );
    if( parameters.getParameter< String >( "device" ) == "cuda" )
-   {
-      writeParameter< String >( "CUDA GPU info", String("") );
-      // 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 = Devices::CudaDeviceInfo::getNumberOfDevices();
-//      writeParameter< int >( "Number of devices", devices, 1 );
-//      for( int i = 0; i < devices; i++ )
-//      {
-//        writeParameter< int >( "Device no.", i, 1 );
-        int i = Devices::CudaDeviceInfo::getActiveDevice();
-        writeParameter< String >( "Name", Devices::CudaDeviceInfo::getDeviceName( i ), 2 );
-        String deviceArch = String( Devices::CudaDeviceInfo::getArchitectureMajor( i ) ) + "." +
-                                String( Devices::CudaDeviceInfo::getArchitectureMinor( i ) );
-        writeParameter< String >( "Architecture", deviceArch, 2 );
-        writeParameter< int >( "CUDA cores", Devices::CudaDeviceInfo::getCudaCores( i ), 2 );
-        double clockRate = ( double ) Devices::CudaDeviceInfo::getClockRate( i ) / 1.0e3;
-        writeParameter< double >( "Clock rate (in MHz)", clockRate, 2 );
-        double globalMemory = ( double ) Devices::CudaDeviceInfo::getGlobalMemory( i ) / 1.0e9;
-        writeParameter< double >( "Global memory (in GB)", globalMemory, 2 );
-        double memoryClockRate = ( double ) Devices::CudaDeviceInfo::getMemoryClockRate( i ) / 1.0e3;
-        writeParameter< double >( "Memory clock rate (in Mhz)", memoryClockRate, 2 );
-        writeParameter< bool >( "ECC enabled", Devices::CudaDeviceInfo::getECCEnabled( i ), 2 );
-//      }
-   }
-   writeParameter< String >( "System:", systemInfo.getSystemName() );
-   writeParameter< String >( "Release:", systemInfo.getSystemRelease() );
-   writeParameter< char* >( "TNL Compiler:", ( char* ) TNL_CPP_COMPILER_NAME );
+      Devices::CudaDeviceInfo::writeDeviceInfo( *this );
    return true;
 }
 
 void Logger :: writeCurrentTime( const char* label )
 {
-   SystemInfo systemInfo;
-   writeParameter< String >( label, systemInfo.getCurrentTime() );
+   writeParameter< String >( label, Devices::Host::getCurrentTime() );
 }
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 template void Logger::writeParameter< char* >( const String&,
-                                                  const String&,
-                                                  const Config::ParameterContainer&,
-                                                  int );
+                                               const String&,
+                                               const Config::ParameterContainer&,
+                                               int );
 template void Logger::writeParameter< double >( const String&,
-                                                   const String&,
-                                                   const Config::ParameterContainer&,
-                                                   int );
-template void Logger::writeParameter< int >( const String&,
                                                 const String&,
                                                 const Config::ParameterContainer&,
                                                 int );
+template void Logger::writeParameter< int >( const String&,
+                                             const String&,
+                                             const Config::ParameterContainer&,
+                                             int );
 
 // TODO: fix this
 //template void Logger :: WriteParameter< char* >( const char*,
-//                                                    const char*&,
-//                                                    int );
+//                                                 const char*&,
+//                                                 int );
 template void Logger::writeParameter< double >( const String&,
-                                                   const double&,
-                                                   int );
-template void Logger::writeParameter< int >( const String&,
-                                                const int&,
+                                                const double&,
                                                 int );
-
+template void Logger::writeParameter< int >( const String&,
+                                             const int&,
+                                             int );
 #endif
 
 } // namespace TNL
diff --git a/src/TNL/Logger.h b/src/TNL/Logger.h
index 90dd927da5547af88ef5b885a2192c449fd3cd74..791398649d8d61f89a984cbb8255bb0be22a69d9 100644
--- a/src/TNL/Logger.h
+++ b/src/TNL/Logger.h
@@ -26,7 +26,6 @@ class Logger
 
    void writeSeparator();
 
-   // TODO: move this to Devices::Host
    bool writeSystemInformation( const Config::ParameterContainer& parameters );
  
 
@@ -59,28 +58,28 @@ namespace TNL {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 extern template void Logger::writeParameter< char* >( const String&,
-                                                         const String&,
-                                                         const Config::ParameterContainer&,
-                                                         int );
+                                                      const String&,
+                                                      const Config::ParameterContainer&,
+                                                      int );
 extern template void Logger::writeParameter< double >( const String&,
-                                                          const String&,
-                                                          const Config::ParameterContainer&,
-                                                          int );
-extern template void Logger::writeParameter< int >( const String&,
                                                        const String&,
                                                        const Config::ParameterContainer&,
                                                        int );
+extern template void Logger::writeParameter< int >( const String&,
+                                                    const String&,
+                                                    const Config::ParameterContainer&,
+                                                    int );
 
 // TODO: fix this
 //extern template void Logger :: WriteParameter< char* >( const char*,
-//                                                           const char*&,
-//                                                           int );
+//                                                        const char*&,
+//                                                        int );
 extern template void Logger::writeParameter< double >( const String&,
-                                                          const double&,
-                                                          int );
-extern template void Logger::writeParameter< int >( const String&,
-                                                       const int&,
+                                                       const double&,
                                                        int );
+extern template void Logger::writeParameter< int >( const String&,
+                                                    const int&,
+                                                    int );
 #endif
 
 } // namespace TNL
diff --git a/src/TNL/Math.h b/src/TNL/Math.h
index 62ff2bb95e7aaac0b7e9686ef43019f58cff9ae0..e6993069e55cf9a999df56a06588ca13ac5231e3 100644
--- a/src/TNL/Math.h
+++ b/src/TNL/Math.h
@@ -12,159 +12,107 @@
 
 #include <cmath>
 #include <type_traits>
+#include <algorithm>
 
-#include <TNL/Devices/Cuda.h>
-
-#ifdef HAVE_CUDA
-#include <cuda.h>
-#endif
+#include <TNL/Devices/CudaCallable.h>
 
 namespace TNL {
 
 template< typename T1, typename T2 >
 using enable_if_same_base = std::enable_if< std::is_same< typename std::decay< T1 >::type, T2 >::value, T2 >;
 
+template< typename T1, typename T2 >
+using both_integral_or_floating = typename std::conditional<
+         ( std::is_integral< T1 >::value && std::is_integral< T2 >::value ) ||
+         ( std::is_floating_point< T1 >::value && std::is_floating_point< T2 >::value ),
+   std::true_type,
+   std::false_type >::type;
+
+// 1. If both types are integral or floating-point, the larger type is selected.
+// 2. If one type is integral and the other floating-point, the floating-point type is selected.
+// Casting both arguments to the same type is necessary because std::min and std::max
+// are implemented as a single-type template.
+template< typename T1, typename T2 >
+using larger_type = typename std::conditional<
+         ( both_integral_or_floating< T1, T2 >::value && sizeof(T1) >= sizeof(T2) ) ||
+         std::is_floating_point<T1>::value,
+   T1, T2 >::type;
+
 /***
  * This function returns minimum of two numbers.
- * Specializations use the functions defined in the CUDA's math_functions.h
- * in CUDA device code and STL functions otherwise.
+ * GPU device code uses the functions defined in the CUDA's math_functions.h,
+ * MIC uses trivial override and host uses the STL functions.
  */
-template< typename Type1, typename Type2 >
+template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
 __cuda_callable__ inline
-Type1 min( const Type1& a, const Type2& b )
+ResultType min( const T1& a, const T2& b )
 {
+#if defined(__CUDA_ARCH__)
+   return ::min( (ResultType) a, (ResultType) b );
+#elif defined(__MIC__)
    return a < b ? a : b;
-};
-
-// specialization for int
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, int >::type
-min( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::min( a, b );
-#else
-   return std::min( a, b );
-#endif
-}
-
-// specialization for float
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, float >::type
-min( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::fminf( a, b );
 #else
-   return std::fmin( a, b );
-#endif
-}
-
-// specialization for double
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, double >::type
-min( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::fmin( a, b );
-#else
-   return std::fmin( a, b );
+   return std::min( (ResultType) a, (ResultType) b );
 #endif
 }
 
 
 /***
  * This function returns maximum of two numbers.
- * Specializations use the functions defined in the CUDA's math_functions.h
- * in CUDA device code and STL functions otherwise.
+ * GPU device code uses the functions defined in the CUDA's math_functions.h,
+ * MIC uses trivial override and host uses the STL functions.
  */
-template< typename Type1, typename Type2 >
+template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
 __cuda_callable__
-Type1 max( const Type1& a, const Type2& b )
+ResultType max( const T1& a, const T2& b )
 {
+#if defined(__CUDA_ARCH__)
+   return ::max( (ResultType) a, (ResultType) b );
+#elif defined(__MIC__)
    return a > b ? a : b;
-};
-
-// specialization for int
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, int >::type
-max( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::max( a, b );
 #else
-   return std::max( a, b );
-#endif
-}
-
-// specialization for float
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, float >::type
-max( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::fmaxf( a, b );
-#else
-   return std::fmax( a, b );
-#endif
-}
-
-// specialization for double
-template< class T >
-__cuda_callable__ inline
-typename enable_if_same_base< T, double >::type
-max( const T& a, const T& b )
-{
-#ifdef __CUDA_ARCH__
-   return ::fmax( a, b );
-#else
-   return std::fmax( a, b );
+   return std::max( (ResultType) a, (ResultType) b );
 #endif
 }
 
 
 /***
  * This function returns absolute value of given number.
- * Specializations use the functions defined in the CUDA's math_functions.h
- * in CUDA device code and STL functions otherwise.
  */
 template< class T >
 __cuda_callable__ inline
-typename std::enable_if< ! std::is_arithmetic< T >::value, T >::type
-abs( const T& n )
+T abs( const T& n )
 {
+#if defined(__MIC__)
    if( n < ( T ) 0 )
       return -n;
    return n;
+#else
+   return std::abs( n );
+#endif
 }
 
-// specialization for any arithmetic type (e.g. int, float, double)
-template< class T >
+
+template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
 __cuda_callable__ inline
-typename std::enable_if< std::is_arithmetic< T >::value, T >::type
-abs( const T& n )
+ResultType pow( const T1& base, const T2& exp )
 {
-#ifdef __CUDA_ARCH__
-   return ::abs( n );
+#if defined(__CUDA_ARCH__) || defined(__MIC__)
+   return ::pow( (ResultType) base, (ResultType) exp );
 #else
-   return std::abs( n );
+   return std::pow( (ResultType) base, (ResultType) exp );
 #endif
 }
 
 
-template< class T >
+template< typename T >
 __cuda_callable__ inline
-T pow( const T& base, const T& exp )
+T sqrt( const T& value )
 {
-#ifdef __CUDA_ARCH__
-   return ::pow( base, exp );
+#if defined(__CUDA_ARCH__) || defined(__MIC__)
+   return ::sqrt( value );
 #else
-   return std::pow( base, exp );
+   return std::sqrt( value );
 #endif
 }
 
@@ -176,16 +124,16 @@ void swap( Type& a, Type& b )
    Type tmp( a );
    a = b;
    b = tmp;
-};
+}
 
 template< class T >
 __cuda_callable__
 T sign( const T& a )
 {
-   if( a < ( T ) 0 ) return -1;
-   if( a == ( T ) 0 ) return 0;
-   return 1;
-};
+   if( a < ( T ) 0 ) return ( T ) -1;
+   if( a == ( T ) 0 ) return ( T ) 0;
+   return ( T ) 1;
+}
 
 template< typename Real >
 __cuda_callable__
@@ -220,4 +168,3 @@ inline bool isPow2( long int x )
 }
 
 } // namespace TNL
-
diff --git a/src/TNL/Matrices/CMakeLists.txt b/src/TNL/Matrices/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Matrices/CSR.h b/src/TNL/Matrices/CSR.h
index e42fca6b73990d05e1d5312d61b7022ecc6f2b49..e3d6253e8a09d27404f78801ef44c7ee2699ba81 100644
--- a/src/TNL/Matrices/CSR.h
+++ b/src/TNL/Matrices/CSR.h
@@ -30,17 +30,27 @@ class CSRDeviceDependentCode;
 template< typename Real, typename Device = Devices::Host, typename Index = int >
 class CSR : public Sparse< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
+
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class CSR;
+
+public:
 
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Sparse< RealType, DeviceType, IndexType >:: CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Sparse< RealType, DeviceType, IndexType >:: CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef CSR< Real, Device, Index > ThisType;
    typedef CSR< Real, Devices::Host, Index > HostType;
    typedef CSR< Real, Devices::Cuda, Index > CudaType;
    typedef Sparse< Real, Device, Index > BaseType;
    typedef typename BaseType::MatrixRow MatrixRow;
+   typedef SparseRow< const RealType, const IndexType > ConstMatrixRow;
 
 
    enum SPMVCudaKernel { scalar, vector, hybrid };
@@ -51,15 +61,22 @@ class CSR : public Sparse< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const CSR< Real2, Device2, Index2 >& matrix );
+   void setLike( const CSR< Real2, Device2, Index2 >& matrix );
 
    void reset();
 
@@ -125,7 +142,7 @@ class CSR : public Sparse< Real, Device, Index >
    MatrixRow getRow( const IndexType rowIndex );
 
    __cuda_callable__
-   const MatrixRow getRow( const IndexType rowIndex ) const;
+   ConstMatrixRow getRow( const IndexType rowIndex ) const;
 
    template< typename Vector >
    __cuda_callable__
@@ -153,6 +170,14 @@ class CSR : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   CSR& operator=( const CSR& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   CSR& operator=( const CSR< Real2, Device2, Index2 >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -198,7 +223,45 @@ class CSR : public Sparse< Real, Device, Index >
                            int gridIdx ) const;
 #endif
 
-   protected:
+   // The following getters allow us to interface TNL with external C-like
+   // libraries such as UMFPACK or SuperLU, which need the raw data.
+   const Containers::Vector< Index, Device, Index >&
+   getRowPointers() const
+   {
+      return this->rowPointers;
+   }
+
+   Containers::Vector< Index, Device, Index >&
+   getRowPointers()
+   {
+      return this->rowPointers;
+   }
+
+   const Containers::Vector< Index, Device, Index >&
+   getColumnIndexes() const
+   {
+      return this->columnIndexes;
+   }
+
+   Containers::Vector< Index, Device, Index >&
+   getColumnIndexes()
+   {
+      return this->columnIndexes;
+   }
+
+   const Containers::Vector< Real, Device, Index >&
+   getValues() const
+   {
+      return this->values;
+   }
+
+   Containers::Vector< Real, Device, Index >&
+   getValues()
+   {
+      return this->values;
+   }
+
+protected:
 
    Containers::Vector< Index, Device, Index > rowPointers;
 
@@ -209,15 +272,9 @@ class CSR : public Sparse< Real, Device, Index >
    typedef CSRDeviceDependentCode< DeviceType > DeviceDependentCode;
    friend class CSRDeviceDependentCode< DeviceType >;
    friend class tnlCusparseCSR< RealType >;
-#ifdef HAVE_UMFPACK
-    template< typename Matrix, typename Preconditioner >
-    friend class UmfpackWrapper;
-#endif
-
 };
 
 } // namespace Matrices
 } // namespace TNL
 
 #include <TNL/Matrices/CSR_impl.h>
-
diff --git a/src/TNL/Matrices/CSR_impl.h b/src/TNL/Matrices/CSR_impl.h
index 6d52662577bf6ad976b066e1b524f0665de9fd96..0b47633ea9a78b906822bc1e0466e196846dd774 100644
--- a/src/TNL/Matrices/CSR_impl.h
+++ b/src/TNL/Matrices/CSR_impl.h
@@ -12,7 +12,6 @@
 
 #include <TNL/Matrices/CSR.h>
 #include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Math.h>
 
 #ifdef HAVE_CUSPARSE
@@ -61,30 +60,46 @@ String CSR< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                         const IndexType columns )
+String CSR< Real, Device, Index >::getSerializationType()
 {
-   if( ! Sparse< Real, Device, Index >::setDimensions( rows, columns ) ||
-       ! this->rowPointers.setSize( this->rows + 1 ) )
-      return false;
+   return HostType::getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String CSR< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void CSR< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                const IndexType columns )
+{
+   Sparse< Real, Device, Index >::setDimensions( rows, columns );
+   this->rowPointers.setSize( this->rows + 1 );
    this->rowPointers.setValue( 0 );
-   return true;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void CSR< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
+   TNL_ASSERT_GT( this->getRows(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_GT( this->getColumns(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_EQ( this->getRows(), rowLengths.getSize(), "wrong size of the rowLengths vector" );
+
    /****
     * Compute the rows pointers. The last one is
     * the end of the last row and so it says the
     * necessary length of the vectors this->values
     * and this->columnIndexes.
     */
-   Assert( this->getRows() > 0, );
-   Assert( this->getColumns() > 0, );
-   Containers::SharedVector< IndexType, DeviceType, IndexType > rowPtrs;
+   Containers::Vector< IndexType, DeviceType, IndexType > rowPtrs;
    rowPtrs.bind( this->rowPointers.getData(), this->getRows() );
    rowPtrs = rowLengths;
    this->rowPointers.setElement( this->rows, 0 );
@@ -94,17 +109,24 @@ bool CSR< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsL
    /****
     * Allocate values and column indexes
     */
-   if( ! this->values.setSize( this->rowPointers.getElement( this->rows ) ) ||
-       ! this->columnIndexes.setSize( this->rowPointers.getElement( this->rows ) ) )
-      return false;
+   this->values.setSize( this->rowPointers.getElement( this->rows ) );
+   this->columnIndexes.setSize( this->rowPointers.getElement( this->rows ) );
    this->columnIndexes.setValue( this->columns );
-   return true;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 Index CSR< Real, Device, Index >::getRowLength( const IndexType row ) const
+{
+   return this->rowPointers.getElement( row + 1 ) - this->rowPointers.getElement( row );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index CSR< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
 {
    return this->rowPointers[ row + 1 ] - this->rowPointers[ row ];
 }
@@ -115,12 +137,10 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool CSR< Real, Device, Index >::setLike( const CSR< Real2, Device2, Index2 >& matrix )
+void CSR< Real, Device, Index >::setLike( const CSR< Real2, Device2, Index2 >& matrix )
 {
-   if( ! Sparse< Real, Device, Index >::setLike( matrix ) ||
-       ! this->rowPointers.setLike( matrix.rowPointers ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::setLike( matrix );
+   this->rowPointers.setLike( matrix.rowPointers );
 }
 
 template< typename Real,
@@ -163,7 +183,7 @@ bool CSR< Real, Device, Index >::addElementFast( const IndexType row,
                                                           const RealType& value,
                                                           const RealType& thisElementMultiplicator )
 {
-   /*Assert( row >= 0 && row < this->rows &&
+   /*TNL_ASSERT( row >= 0 && row < this->rows &&
               column >= 0 && column <= this->rows,
               std::cerr << " row = " << row
                    << " column = " << column
@@ -213,7 +233,7 @@ bool CSR< Real, Device, Index >::addElement( const IndexType row,
                                                       const RealType& value,
                                                       const RealType& thisElementMultiplicator )
 {
-   Assert( row >= 0 && row < this->rows &&
+   TNL_ASSERT( row >= 0 && row < this->rows &&
                column >= 0 && column < this->columns,
                std::cerr << " row = " << row
                     << " column = " << column
@@ -271,7 +291,7 @@ bool CSR< Real, Device, Index > :: setRowFast( const IndexType row,
 
    for( IndexType i = 0; i < elements; i++ )
    {
-      printf( "Setting element row: %d column: %d value: %f \n", row, columnIndexes[ i ], values[ i ] );
+      //printf( "Setting element row: %d column: %d value: %f \n", row, columnIndexes[ i ], values[ i ] );
       this->columnIndexes[ elementPointer ] = columnIndexes[ i ];
       this->values[ elementPointer ] = values[ i ];
       elementPointer++;
@@ -406,16 +426,16 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__
-const typename CSR< Real, Device, Index >::MatrixRow
+typename CSR< Real, Device, Index >::ConstMatrixRow
 CSR< Real, Device, Index >::
 getRow( const IndexType rowIndex ) const
 {
    const IndexType rowOffset = this->rowPointers[ rowIndex ];
    const IndexType rowLength = this->rowPointers[ rowIndex + 1 ] - rowOffset;
-   return MatrixRow( &this->columnIndexes[ rowOffset ],
-                     &this->values[ rowOffset ],
-                     rowLength,
-                     1 );
+   return ConstMatrixRow( &this->columnIndexes[ rowOffset ],
+                          &this->values[ rowOffset ],
+                          rowLength,
+                          1 );
 }
 
 template< typename Real,
@@ -455,7 +475,7 @@ void CSR< Real, Device, Index >::addMatrix( const CSR< Real2, Device, Index2 >&
                                             const RealType& matrixMultiplicator,
                                             const RealType& thisMatrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -467,7 +487,7 @@ template< typename Real,
 void CSR< Real, Device, Index >::getTransposition( const CSR< Real2, Device, Index2 >& matrix,
                                                                       const RealType& matrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -480,7 +500,7 @@ bool CSR< Real, Device, Index >::performSORIteration( const Vector& b,
                                                       Vector& x,
                                                       const RealType& omega ) const
 {
-   Assert( row >=0 && row < this->getRows(),
+   TNL_ASSERT( row >=0 && row < this->getRows(),
               std::cerr << "row = " << row
                    << " this->getRows() = " << this->getRows() << std::endl );
 
@@ -508,6 +528,36 @@ bool CSR< Real, Device, Index >::performSORIteration( const Vector& b,
 }
 
 
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+CSR< Real, Device, Index >&
+CSR< Real, Device, Index >::operator=( const CSR& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->columnIndexes = matrix.columnIndexes;
+   this->rowPointers = matrix.rowPointers;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+CSR< Real, Device, Index >&
+CSR< Real, Device, Index >::operator=( const CSR< Real2, Device2, Index2 >& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->columnIndexes = matrix.columnIndexes;
+   this->rowPointers = matrix.rowPointers;
+   return *this;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -629,7 +679,7 @@ void CSR< Real, Device, Index >::spmvCudaVectorized( const InVector& inVector,
                                                               const IndexType warpEnd,
                                                               const IndexType inWarpIdx ) const
 {
-   volatile Real* aux = Devices::getSharedMemory< Real >();
+   volatile Real* aux = Devices::Cuda::getSharedMemory< Real >();
    for( IndexType row = warpStart; row < warpEnd; row++ )
    {
       aux[ threadIdx.x ] = 0.0;
@@ -723,7 +773,7 @@ class CSRDeviceDependentCode< Devices::Host >
          const InVector* inVectorPtr = &inVector;
          OutVector* outVectorPtr = &outVector;
 #ifdef HAVE_OPENMP
-#pragma omp parallel for firstprivate( matrixPtr, inVectorPtr, outVectorPtr ), schedule(static ), if( Devices::Host::isOMPEnabled() )
+#pragma omp parallel for firstprivate( matrixPtr, inVectorPtr, outVectorPtr ), schedule(dynamic,100), if( Devices::Host::isOMPEnabled() )
 #endif
          for( Index row = 0; row < rows; row ++ )
             ( *outVectorPtr )[ row ] = matrixPtr->rowVectorProduct( row, *inVectorPtr );
@@ -731,6 +781,38 @@ class CSRDeviceDependentCode< Devices::Host >
 
 };
 
+#ifdef HAVE_MIC
+template<>
+class CSRDeviceDependentCode< Devices::MIC >
+{
+   public:
+
+      typedef Devices::MIC Device;
+
+      template< typename Real,
+                typename Index,
+                typename InVector,
+                typename OutVector >
+      static void vectorProduct( const CSR< Real, Device, Index >& matrix,      
+                                 const InVector& inVector,
+                                 OutVector& outVector )
+      {
+          cout <<"Not Implemented YET tnlCSRMatrixDeviceDependentCode for MIC" <<endl;
+      };
+  /*       const Index rows = matrix.getRows();
+         const tnlCSRMatrix< Real, Device, Index >* matrixPtr = &matrix;
+         const InVector* inVectorPtr = &inVector;
+         OutVector* outVectorPtr = &outVector;
+#ifdef HAVE_OPENMP
+#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 );
+      }*/
+
+};
+#endif
+
 #ifdef HAVE_CUDA
 template< typename Real,
           typename Index,
@@ -773,7 +855,7 @@ void CSRVectorProductCuda( const CSR< Real, Devices::Cuda, Index >& matrix,
    Matrix* kernel_this = Devices::Cuda::passToDevice( matrix );
    InVector* kernel_inVector = Devices::Cuda::passToDevice( inVector );
    OutVector* kernel_outVector = Devices::Cuda::passToDevice( outVector );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
    dim3 cudaBlockSize( 256 ), cudaGridSize( Devices::Cuda::getMaxGridSize() );
    const IndexType cudaBlocks = roundUpDivision( matrix.getRows(), cudaBlockSize.x );
    const IndexType cudaGrids = roundUpDivision( cudaBlocks, Devices::Cuda::getMaxGridSize() );
@@ -826,11 +908,11 @@ void CSRVectorProductCuda( const CSR< Real, Devices::Cuda, Index >& matrix,
                                               gridIdx );
 
    }
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
    Devices::Cuda::freeFromDevice( kernel_this );
    Devices::Cuda::freeFromDevice( kernel_inVector );
    Devices::Cuda::freeFromDevice( kernel_outVector );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
 #endif
 }
 
diff --git a/src/TNL/Matrices/ChunkedEllpack.h b/src/TNL/Matrices/ChunkedEllpack.h
index a6a1d96f712fe6ba5b619f1a8ee4de9428fa6ad3..ba14092163815ca30e7f296705d00013ed84e124 100644
--- a/src/TNL/Matrices/ChunkedEllpack.h
+++ b/src/TNL/Matrices/ChunkedEllpack.h
@@ -62,18 +62,27 @@ __global__ void ChunkedEllpackVectorProductCudaKernel( const ChunkedEllpack< Rea
 template< typename Real, typename Device, typename Index >
 class ChunkedEllpack : public Sparse< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class ChunkedEllpack;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
    typedef tnlChunkedEllpackSliceInfo< IndexType > ChunkedEllpackSliceInfo;
-   typedef typename Sparse< RealType, DeviceType, IndexType >:: CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Sparse< RealType, DeviceType, IndexType >:: CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef ChunkedEllpack< Real, Device, Index > ThisType;
    typedef ChunkedEllpack< Real, Devices::Host, Index > HostType;
    typedef ChunkedEllpack< Real, Devices::Cuda, Index > CudaType;
    typedef Sparse< Real, Device, Index > BaseType;
    typedef typename BaseType::MatrixRow MatrixRow;
+   typedef SparseRow< const RealType, const IndexType > ConstMatrixRow;
 
    ChunkedEllpack();
 
@@ -81,15 +90,22 @@ class ChunkedEllpack : public Sparse< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const ChunkedEllpack< Real2, Device2, Index2 >& matrix );
+   void setLike( const ChunkedEllpack< Real2, Device2, Index2 >& matrix );
 
    void reset();
 
@@ -178,7 +194,7 @@ class ChunkedEllpack : public Sparse< Real, Device, Index >
    MatrixRow getRow( const IndexType rowIndex );
 
    __cuda_callable__
-   const MatrixRow getRow( const IndexType rowIndex ) const;
+   ConstMatrixRow getRow( const IndexType rowIndex ) const;
 
    template< typename Vector >
    __cuda_callable__
@@ -214,6 +230,14 @@ class ChunkedEllpack : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   ChunkedEllpack& operator=( const ChunkedEllpack& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   ChunkedEllpack& operator=( const ChunkedEllpack< Real2, Device2, Index2 >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -227,12 +251,11 @@ class ChunkedEllpack : public Sparse< Real, Device, Index >
    void printStructure( std::ostream& str,
                         const String& = "" ) const;
 
-   protected:
-
+protected:
 
    void resolveSliceSizes( const Containers::Vector< Index, Devices::Host, Index >& rowLengths );
 
-   bool setSlice( const CompressedRowsLengthsVector& rowLengths,
+   bool setSlice( const CompressedRowLengthsVector& rowLengths,
                   const IndexType sliceIdx,
                   IndexType& elementsToAllocation );
 
diff --git a/src/TNL/Matrices/ChunkedEllpack_impl.h b/src/TNL/Matrices/ChunkedEllpack_impl.h
index 325ae861ab985f517879a3aeb4ea4076cedcb003..5c5c71543c82c10cc2da55728fd7352d83b943b0 100644
--- a/src/TNL/Matrices/ChunkedEllpack_impl.h
+++ b/src/TNL/Matrices/ChunkedEllpack_impl.h
@@ -14,10 +14,6 @@
 #include <TNL/Containers/Vector.h>
 #include <TNL/Math.h>
 
-#ifdef HAVE_CUDA
-#include <cuda.h>
-#endif
-
 namespace TNL {
 namespace Matrices {   
 
@@ -62,25 +58,38 @@ String ChunkedEllpack< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                                    const IndexType columns )
+String ChunkedEllpack< Real, Device, Index >::getSerializationType()
+{
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String ChunkedEllpack< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void ChunkedEllpack< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                           const IndexType columns )
 {
-   Assert( rows > 0 && columns > 0,
+   TNL_ASSERT( rows > 0 && columns > 0,
               std::cerr << "rows = " << rows
                    << " columns = " << columns << std::endl );
-   if( ! Sparse< Real, Device, Index >::setDimensions( rows, columns ) )
-      return false;
+   Sparse< Real, Device, Index >::setDimensions( rows, columns );
 
    /****
     * Allocate slice info array. Note that there cannot be
     * more slices than rows.
     */
-   if( ! this->slices.setSize( this->rows ) ||
-       ! this->rowToChunkMapping.setSize( this-> rows ) ||
-       ! this->rowToSliceMapping.setSize( this->rows ) ||
-       ! this->rowPointers.setSize( this->rows + 1 ) )
-      return false;
-   return true;
+   this->slices.setSize( this->rows );
+   this->rowToChunkMapping.setSize( this-> rows );
+   this->rowToSliceMapping.setSize( this->rows );
+   this->rowPointers.setSize( this->rows + 1 );
 }
 
 template< typename Real,
@@ -110,7 +119,7 @@ void ChunkedEllpack< Real, Device, Index >::resolveSliceSizes( const Containers:
       row++;
       if( allocatedElementsInSlice < desiredElementsInSlice  )
           if( row < this->rows && sliceSize < chunksInSlice ) continue;
-      Assert( sliceSize >0, );
+      TNL_ASSERT( sliceSize >0, );
       this->slices[ numberOfSlices ].size = sliceSize;
       this->slices[ numberOfSlices ].firstRow = row - sliceSize;
       this->slices[ numberOfSlices ].pointer = allocatedElementsInSlice; // this is only temporary
@@ -123,7 +132,7 @@ void ChunkedEllpack< Real, Device, Index >::resolveSliceSizes( const Containers:
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::setSlice( const CompressedRowsLengthsVector& rowLengths,
+bool ChunkedEllpack< Real, Device, Index >::setSlice( const CompressedRowLengthsVector& rowLengths,
                                                                const IndexType sliceIndex,
                                                                IndexType& elementsToAllocation )
 {
@@ -173,7 +182,7 @@ bool ChunkedEllpack< Real, Device, Index >::setSlice( const CompressedRowsLength
       maxChunkInSlice = max( maxChunkInSlice,
                           ceil( ( RealType ) rowLengths[ i ] /
                                 ( RealType ) this->rowToChunkMapping[ i ] ) );
-   Assert( maxChunkInSlice > 0,
+   TNL_ASSERT( maxChunkInSlice > 0,
               std::cerr << " maxChunkInSlice = " << maxChunkInSlice << std::endl );
 
    /****
@@ -189,9 +198,9 @@ bool ChunkedEllpack< Real, Device, Index >::setSlice( const CompressedRowsLength
    for( IndexType i = sliceBegin; i < sliceEnd; i++ )
    {
       this->rowPointers[ i + 1 ] = maxChunkInSlice*rowToChunkMapping[ i ];
-      Assert( this->rowPointers[ i ] >= 0,
+      TNL_ASSERT( this->rowPointers[ i ] >= 0,
                  std::cerr << "this->rowPointers[ i ] = " << this->rowPointers[ i ] );
-      Assert( this->rowPointers[ i + 1 ] >= 0,
+      TNL_ASSERT( this->rowPointers[ i + 1 ] >= 0,
                  std::cerr << "this->rowPointers[ i + 1 ] = " << this->rowPointers[ i + 1 ] );
    }
 
@@ -206,10 +215,11 @@ bool ChunkedEllpack< Real, Device, Index >::setSlice( const CompressedRowsLength
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void ChunkedEllpack< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
-   Assert( this->getRows() > 0, );
-   Assert( this->getColumns() > 0, );
+   TNL_ASSERT_GT( this->getRows(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_GT( this->getColumns(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_EQ( this->getRows(), rowLengths.getSize(), "wrong size of the rowLengths vector" );
 
    IndexType elementsToAllocation( 0 );
 
@@ -226,12 +236,12 @@ bool ChunkedEllpack< Real, Device, Index >::setCompressedRowsLengths( const Comp
    {
       ChunkedEllpack< RealType, Devices::Host, IndexType > hostMatrix;
       hostMatrix.setDimensions( this->getRows(), this->getColumns() );
-      Containers::Vector< IndexType, Devices::Host, IndexType > hostCompressedRowsLengths;
-      hostCompressedRowsLengths.setLike( rowLengths);
-      hostCompressedRowsLengths = rowLengths;
+      Containers::Vector< IndexType, Devices::Host, IndexType > hostCompressedRowLengths;
+      hostCompressedRowLengths.setLike( rowLengths);
+      hostCompressedRowLengths = rowLengths;
       hostMatrix.setNumberOfChunksInSlice( this->chunksInSlice );
       hostMatrix.setDesiredChunkSize( this->desiredChunkSize );
-      hostMatrix.setCompressedRowsLengths( hostCompressedRowsLengths );
+      hostMatrix.setCompressedRowLengths( hostCompressedRowLengths );
 
       this->rowToChunkMapping.setLike( hostMatrix.rowToChunkMapping );
       this->rowToChunkMapping = hostMatrix.rowToChunkMapping;
@@ -245,7 +255,7 @@ bool ChunkedEllpack< Real, Device, Index >::setCompressedRowsLengths( const Comp
       elementsToAllocation = hostMatrix.values.getSize();
    }
    this->maxRowLength = rowLengths.max();
-   return Sparse< Real, Device, Index >::allocateMatrixElements( elementsToAllocation );
+   Sparse< Real, Device, Index >::allocateMatrixElements( elementsToAllocation );
 }
 
 template< typename Real,
@@ -253,9 +263,21 @@ template< typename Real,
           typename Index >
 Index ChunkedEllpack< Real, Device, Index >::getRowLength( const IndexType row ) const
 {
-   const IndexType& sliceIndex = rowToSliceMapping[ row ];
-   Assert( sliceIndex < this->rows, );
+   const IndexType& sliceIndex = rowToSliceMapping.getElement( row );
+   TNL_ASSERT( sliceIndex < this->rows, );
    const IndexType& chunkSize = slices.getElement( sliceIndex ).chunkSize;
+   return rowPointers.getElement( row + 1 ) - rowPointers.getElement( row );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index ChunkedEllpack< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
+{
+   const IndexType& sliceIndex = rowToSliceMapping[ row ];
+   TNL_ASSERT( sliceIndex < this->rows, );
+   const IndexType& chunkSize = slices[ sliceIndex ].chunkSize;
    return rowPointers[ row + 1 ] - rowPointers[ row ];
 }
 
@@ -265,16 +287,14 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool ChunkedEllpack< Real, Device, Index >::setLike( const ChunkedEllpack< Real2, Device2, Index2 >& matrix )
+void ChunkedEllpack< Real, Device, Index >::setLike( const ChunkedEllpack< Real2, Device2, Index2 >& matrix )
 {
    this->chunksInSlice = matrix.chunksInSlice;
    this->desiredChunkSize = matrix.desiredChunkSize;
-   if( ! Sparse< Real, Device, Index >::setLike( matrix ) ||
-       ! this->rowToChunkMapping.setLike( matrix.rowToChunkMapping ) ||
-       ! this->rowToSliceMapping.setLike( matrix.rowToSliceMapping ) ||
-       ! this->slices.setLike( matrix.slices ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::setLike( matrix );
+   this->rowToChunkMapping.setLike( matrix.rowToChunkMapping );
+   this->rowToSliceMapping.setLike( matrix.rowToSliceMapping );
+   this->slices.setLike( matrix.slices );
 }
 
 template< typename Real,
@@ -338,7 +358,7 @@ template< typename Real,
              typename Index2 >
 bool ChunkedEllpack< Real, Device, Index >::operator == ( const ChunkedEllpack< Real2, Device2, Index2 >& matrix ) const
 {
-   Assert( this->getRows() == matrix.getRows() &&
+   TNL_ASSERT( this->getRows() == matrix.getRows() &&
               this->getColumns() == matrix.getColumns(),
               std::cerr << "this->getRows() = " << this->getRows()
                    << " matrix.getRows() = " << matrix.getRows()
@@ -390,7 +410,7 @@ bool ChunkedEllpack< Real, Device, Index >::addElementFast( const IndexType row,
                                                                      const RealType& _thisElementMultiplicator )
 {
    // TODO: return this back when CUDA kernels support std::cerr
-   /*Assert( row >= 0 && row < this->rows &&
+   /*TNL_ASSERT( row >= 0 && row < this->rows &&
               _column >= 0 && _column <= this->columns,
               std::cerr << " row = " << row
                    << " column = " << _column
@@ -398,7 +418,7 @@ bool ChunkedEllpack< Real, Device, Index >::addElementFast( const IndexType row,
                    << " this->columns = " << this-> columns );*/
 
    const IndexType& sliceIndex = rowToSliceMapping[ row ];
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices[ sliceIndex ].firstRow )
       chunkIndex = rowToChunkMapping[ row - 1 ];
@@ -489,7 +509,7 @@ bool ChunkedEllpack< Real, Device, Index >::addElement( const IndexType row,
                                                                  const RealType& _value,
                                                                  const RealType& _thisElementMultiplicator )
 {
-   Assert( row >= 0 && row < this->rows &&
+   TNL_ASSERT( row >= 0 && row < this->rows &&
               _column >= 0 && _column <= this->columns,
               std::cerr << " row = " << row
                    << " column = " << _column
@@ -497,7 +517,7 @@ bool ChunkedEllpack< Real, Device, Index >::addElement( const IndexType row,
                    << " this->columns = " << this-> columns );
 
    const IndexType& sliceIndex = rowToSliceMapping.getElement( row );
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices.getElement( sliceIndex ).firstRow )
       chunkIndex = rowToChunkMapping.getElement( row - 1 );
@@ -586,11 +606,11 @@ bool ChunkedEllpack< Real, Device, Index >::setRowFast( const IndexType row,
                                                                  const IndexType elements )
 {
    // TODO: return this back when CUDA kernels support std::cerr
-   /*Assert( row >= 0 && row < this->rows,
+   /*TNL_ASSERT( row >= 0 && row < this->rows,
               std::cerr << " row = " << row
                    << " this->rows = " << this->rows );*/
    const IndexType sliceIndex = rowToSliceMapping[ row ];
-   //Assert( sliceIndex < this->rows, );
+   //TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices[ sliceIndex ].firstRow )
       chunkIndex = rowToChunkMapping[ row - 1 ];
@@ -661,12 +681,12 @@ bool ChunkedEllpack< Real, Device, Index >::setRow( const IndexType row,
                                                              const RealType* values,
                                                              const IndexType elements )
 {
-   Assert( row >= 0 && row < this->rows,
+   TNL_ASSERT( row >= 0 && row < this->rows,
               std::cerr << " row = " << row
                    << " this->rows = " << this->rows );
 
    const IndexType sliceIndex = rowToSliceMapping.getElement( row );
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices.getElement( sliceIndex ).firstRow )
       chunkIndex = rowToChunkMapping.getElement( row - 1 );
@@ -762,7 +782,7 @@ Real ChunkedEllpack< Real, Device, Index >::getElementFast( const IndexType row,
                                                                      const IndexType column ) const
 {
    const IndexType sliceIndex = rowToSliceMapping[ row ];
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices[ sliceIndex ].firstRow )
       chunkIndex = rowToChunkMapping[ row - 1 ];
@@ -808,7 +828,7 @@ Real ChunkedEllpack< Real, Device, Index >::getElement( const IndexType row,
                                                                  const IndexType column ) const
 {
    const IndexType& sliceIndex = rowToSliceMapping.getElement( row );
-   Assert( sliceIndex < this->rows,
+   TNL_ASSERT( sliceIndex < this->rows,
               std::cerr << " sliceIndex = " << sliceIndex
                    << " this->rows = " << this->rows << std::endl; );
    IndexType chunkIndex( 0 );
@@ -863,7 +883,7 @@ void ChunkedEllpack< Real, Device, Index >::getRowFast( const IndexType row,
                                                                  RealType* values ) const
 {
    const IndexType& sliceIndex = rowToSliceMapping[ row ];
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices[ sliceIndex ].firstRow )
       chunkIndex = rowToChunkMapping[ row - 1 ];
@@ -916,7 +936,7 @@ getRow( const IndexType rowIndex )
 {
    const IndexType rowOffset = this->rowPointers[ rowIndex ];
    const IndexType rowLength = this->rowPointers[ rowIndex + 1 ] - rowOffset;
-   return MatrixRow( &this->columns[ rowOffset ],
+   return MatrixRow( &this->columnIndexes[ rowOffset ],
                      &this->values[ rowOffset ],
                      rowLength,
                      1 );
@@ -926,13 +946,13 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__
-const typename ChunkedEllpack< Real, Device, Index >::MatrixRow
+typename ChunkedEllpack< Real, Device, Index >::ConstMatrixRow
 ChunkedEllpack< Real, Device, Index >::
 getRow( const IndexType rowIndex ) const
 {
    const IndexType rowOffset = this->rowPointers[ rowIndex ];
    const IndexType rowLength = this->rowPointers[ rowIndex + 1 ] - rowOffset;
-   return MatrixRow( &this->columns[ rowOffset ],
+   return MatrixRow( &this->columnIndexes[ rowOffset ],
                      &this->values[ rowOffset ],
                      rowLength,
                      1 );
@@ -947,7 +967,7 @@ void ChunkedEllpack< Real, Device, Index >::getRow( const IndexType row,
                                                              RealType* values ) const
 {
    const IndexType& sliceIndex = rowToSliceMapping.getElement( row );
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices.getElement( sliceIndex ).firstRow )
       chunkIndex = rowToChunkMapping.getElement( row - 1 );
@@ -1003,11 +1023,11 @@ __cuda_callable__
 typename Vector::RealType ChunkedEllpack< Real, Device, Index >::rowVectorProduct( const IndexType row,
                                                                                             const Vector& vector ) const
 {
-   /*Assert( row >=0 && row < this->rows,
+   /*TNL_ASSERT( row >=0 && row < this->rows,
             std::cerr << " row = " << row << " this->rows = " << this->rows );*/
 
    const IndexType sliceIndex = rowToSliceMapping[ row ];
-   //Assert( sliceIndex < this->rows, );
+   //TNL_ASSERT( sliceIndex < this->rows, );
    IndexType chunkIndex( 0 );
    if( row != slices[ sliceIndex ].firstRow )
       chunkIndex = rowToChunkMapping[ row - 1 ];
@@ -1068,7 +1088,7 @@ __device__ void ChunkedEllpack< Real, Device, Index >::computeSliceVectorProduct
 {
    static_assert( std::is_same < DeviceType, Devices::Cuda >::value, "" );
 
-   RealType* chunkProducts = Devices::getSharedMemory< RealType >();
+   RealType* chunkProducts = Devices::Cuda::getSharedMemory< RealType >();
    ChunkedEllpackSliceInfo* sliceInfo = ( ChunkedEllpackSliceInfo* ) & chunkProducts[ blockDim.x ];
 
    if( threadIdx.x == 0 )
@@ -1115,7 +1135,7 @@ void ChunkedEllpack< Real, Device, Index >::addMatrix( const ChunkedEllpack< Rea
                                                                           const RealType& matrixMultiplicator,
                                                                           const RealType& thisMatrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -1127,7 +1147,7 @@ template< typename Real,
 void ChunkedEllpack< Real, Device, Index >::getTransposition( const ChunkedEllpack< Real2, Device, Index2 >& matrix,
                                                                        const RealType& matrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -1140,7 +1160,7 @@ bool ChunkedEllpack< Real, Device, Index >::performSORIteration( const Vector& b
                                                                                     Vector& x,
                                                                                     const RealType& omega ) const
 {
-   Assert( row >=0 && row < this->getRows(),
+   TNL_ASSERT( row >=0 && row < this->getRows(),
               std::cerr << "row = " << row
                    << " this->getRows() = " << this->getRows() << std::endl );
 
@@ -1148,7 +1168,7 @@ bool ChunkedEllpack< Real, Device, Index >::performSORIteration( const Vector& b
    RealType sum( 0.0 );
 
    const IndexType& sliceIndex = rowToSliceMapping[ row ];
-   Assert( sliceIndex < this->rows, );
+   TNL_ASSERT( sliceIndex < this->rows, );
    const IndexType& chunkSize = slices.getElement( sliceIndex ).chunkSize;
    IndexType elementPtr = rowPointers[ row ];
    const IndexType rowEnd = rowPointers[ row + 1 ];
@@ -1171,6 +1191,46 @@ bool ChunkedEllpack< Real, Device, Index >::performSORIteration( const Vector& b
 }
 
 
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+ChunkedEllpack< Real, Device, Index >&
+ChunkedEllpack< Real, Device, Index >::operator=( const ChunkedEllpack& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->columnIndexes = matrix.columnIndexes;
+   this->chunksInSlice = matrix.chunksInSlice;
+   this->desiredChunkSize = matrix.desiredChunkSize;
+   this->rowToChunkMapping = matrix.rowToChunkMapping;
+   this->rowToSliceMapping = matrix.rowToSliceMapping;
+   this->rowPointers = matrix.rowPointers;
+   this->slices = matrix.slices;
+   this->numberOfSlices = matrix.numberOfSlices;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+ChunkedEllpack< Real, Device, Index >&
+ChunkedEllpack< Real, Device, Index >::operator=( const ChunkedEllpack< Real2, Device2, Index2 >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value,
+                  "unknown device" );
+
+   this->setLike( matrix );
+
+   std::cerr << "Cross-device assignment for the ChunkedEllpack format is not implemented yet." << std::endl;
+   throw 1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -1225,7 +1285,7 @@ void ChunkedEllpack< Real, Device, Index >::print( std::ostream& str ) const
       str <<"Row: " << row << " -> ";
 
       const IndexType& sliceIndex = rowToSliceMapping.getElement( row );
-      //Assert( sliceIndex < this->rows, );
+      //TNL_ASSERT( sliceIndex < this->rows, );
       const IndexType& chunkSize = slices.getElement( sliceIndex ).chunkSize;
       IndexType elementPtr = rowPointers.getElement( row );
       const IndexType rowEnd = rowPointers.getElement( row + 1 );
@@ -1276,7 +1336,7 @@ class ChunkedEllpackDeviceDependentCode< Devices::Host >
       template< typename Real,
                 typename Index >
       static void resolveSliceSizes( ChunkedEllpack< Real, Device, Index >& matrix,
-                                     const typename ChunkedEllpack< Real, Device, Index >::CompressedRowsLengthsVector& rowLengths )
+                                     const typename ChunkedEllpack< Real, Device, Index >::CompressedRowLengthsVector& rowLengths )
       {
          matrix.resolveSliceSizes( rowLengths );
       }
@@ -1337,7 +1397,7 @@ class ChunkedEllpackDeviceDependentCode< Devices::Cuda >
       template< typename Real,
                 typename Index >
       static void resolveSliceSizes( ChunkedEllpack< Real, Device, Index >& matrix,
-                                     const typename ChunkedEllpack< Real, Device, Index >::CompressedRowsLengthsVector& rowLengths )
+                                     const typename ChunkedEllpack< Real, Device, Index >::CompressedRowLengthsVector& rowLengths )
       {
       }
  
@@ -1395,7 +1455,7 @@ class ChunkedEllpackDeviceDependentCode< Devices::Cuda >
             Devices::Cuda::freeFromDevice( kernel_this );
             Devices::Cuda::freeFromDevice( kernel_inVector );
             Devices::Cuda::freeFromDevice( kernel_outVector );
-            checkCudaDevice;
+            TNL_CHECK_CUDA_DEVICE;
          #endif
       }
 
diff --git a/src/TNL/Matrices/Dense.h b/src/TNL/Matrices/Dense.h
index f95c4b626e70d64c4fb41e3cc012fde5a04e6b43..3904f5c059b210ae9b61aa0f1455d4a2ca762964 100644
--- a/src/TNL/Matrices/Dense.h
+++ b/src/TNL/Matrices/Dense.h
@@ -26,12 +26,20 @@ template< typename Real = double,
           typename Index = int >
 class Dense : public Matrix< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class Dense;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Matrix< Real, Device, Index >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Matrix< Real, Device, Index >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef Dense< Real, Device, Index > ThisType;
    typedef Dense< Real, Devices::Host, Index > HostType;
    typedef Dense< Real, Devices::Cuda, Index > CudaType;
@@ -45,16 +53,20 @@ class Dense : public Matrix< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Dense< Real2, Device2, Index2 >& matrix );
+   void setLike( const Dense< Real2, Device2, Index2 >& matrix );
 
    /****
     * This method is only for the compatibility with the sparse matrices.
     */
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    /****
     * Returns maximal number of the nonzero matrix elements that can be stored
@@ -62,6 +74,9 @@ class Dense : public Matrix< Real, Device, Index >
     */
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    IndexType getMaxRowLength() const;
 
    IndexType getNumberOfMatrixElements() const;
@@ -152,29 +167,15 @@ class Dense : public Matrix< Real, Device, Index >
                    const RealType& matrixMultiplicator = 1.0,
                    const RealType& thisMatrixMultiplicator = 1.0 );
 
-#ifdef HAVE_NOT_CXX11
-   template< typename Matrix1, typename Matrix2, int tileDim >
-   void getMatrixProduct( const Matrix1& matrix1,
-                       const Matrix2& matrix2,
-                       const RealType& matrix1Multiplicator = 1.0,
-                       const RealType& matrix2Multiplicator = 1.0 );
-#else
    template< typename Matrix1, typename Matrix2, int tileDim = 32 >
    void getMatrixProduct( const Matrix1& matrix1,
                        const Matrix2& matrix2,
                        const RealType& matrix1Multiplicator = 1.0,
                        const RealType& matrix2Multiplicator = 1.0 );
-#endif
 
-#ifdef HAVE_NOT_CXX11
-   template< typename Matrix, int tileDim >
-   void getTransposition( const Matrix& matrix,
-                          const RealType& matrixMultiplicator = 1.0 );
-#else
    template< typename Matrix, int tileDim = 32 >
    void getTransposition( const Matrix& matrix,
                           const RealType& matrixMultiplicator = 1.0 );
-#endif
 
    template< typename Vector >
    void performSORIteration( const Vector& b,
@@ -182,6 +183,14 @@ class Dense : public Matrix< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   Dense& operator=( const Dense& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   Dense& operator=( const Dense< Real2, Device2, Index2 >& matrix );
+
    bool save( const String& fileName ) const;
 
    bool load( const String& fileName );
@@ -192,7 +201,7 @@ class Dense : public Matrix< Real, Device, Index >
 
    void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
    __cuda_callable__
    IndexType getElementIndex( const IndexType row,
@@ -200,11 +209,9 @@ class Dense : public Matrix< Real, Device, Index >
 
    typedef DenseDeviceDependentCode< DeviceType > DeviceDependentCode;
    friend class DenseDeviceDependentCode< DeviceType >;
-
 };
 
 } // namespace Matrices
 } // namespace TNL
 
 #include <TNL/Matrices/Dense_impl.h>
-
diff --git a/src/TNL/Matrices/DenseRow_impl.h b/src/TNL/Matrices/DenseRow_impl.h
index f49b3ff58804c575132224636cd7d9e5bd63b25e..7b1bac1a5bdc5074b5f22b4d3b5d86046e605011 100644
--- a/src/TNL/Matrices/DenseRow_impl.h
+++ b/src/TNL/Matrices/DenseRow_impl.h
@@ -56,9 +56,9 @@ setElement( const Index& elementIndex,
             const Index& column,
             const Real& value )
 {
-   Assert( this->values, );
-   Assert( this->step > 0,);
-   Assert( column >= 0 && column < this->columns,
+   TNL_ASSERT( this->values, );
+   TNL_ASSERT( this->step > 0,);
+   TNL_ASSERT( column >= 0 && column < this->columns,
               std::cerr << "column = " << column << " this->columns = " << this->columns );
 
    this->values[ column * this->step ] = value;
diff --git a/src/TNL/Matrices/Dense_impl.h b/src/TNL/Matrices/Dense_impl.h
index 5f44c82bfbf1f9a1d0b12795b9386f7f0c812ef0..bb146105eb4d903dd51b105bc5db49da74c4de44 100644
--- a/src/TNL/Matrices/Dense_impl.h
+++ b/src/TNL/Matrices/Dense_impl.h
@@ -49,14 +49,28 @@ String Dense< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                           const IndexType columns )
+String Dense< Real, Device, Index >::getSerializationType()
 {
-   if( ! Matrix< Real, Device, Index >::setDimensions( rows, columns ) ||
-       ! this->values.setSize( rows * columns ) )
-     return false;
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String Dense< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void Dense< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                  const IndexType columns )
+{
+   Matrix< Real, Device, Index >::setDimensions( rows, columns );
+   this->values.setSize( rows * columns );
    this->values.setValue( 0.0 );
-   return true;
 }
 
 template< typename Real,
@@ -65,17 +79,16 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool Dense< Real, Device, Index >::setLike( const Dense< Real2, Device2, Index2 >& matrix )
+void Dense< Real, Device, Index >::setLike( const Dense< Real2, Device2, Index2 >& matrix )
 {
-   return this->setDimensions( matrix.getRows(), matrix.getColumns() );
+   this->setDimensions( matrix.getRows(), matrix.getColumns() );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void Dense< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
-   return true;
 }
 
 template< typename Real,
@@ -86,6 +99,15 @@ Index Dense< Real, Device, Index >::getRowLength( const IndexType row ) const
    return this->getColumns();
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index Dense< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
+{
+   return this->getColumns();
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -141,7 +163,7 @@ bool Dense< Real, Device, Index >::setElementFast( const IndexType row,
                                                             const IndexType column,
                                                             const RealType& value )
 {
-   Assert( row >= 0 && row < this->getRows() &&
+   TNL_ASSERT( row >= 0 && row < this->getRows() &&
               column >= 0 && column < this->getColumns(),
               std::cerr << " row = " << row << " column = " << column << " this->getRows() = " << this->getRows()
                    << " this->getColumns() = " << this->getColumns() );
@@ -153,8 +175,8 @@ template< typename Real,
           typename Device,
           typename Index >
 bool Dense< Real, Device, Index >::setElement( const IndexType row,
-                                                        const IndexType column,
-                                                        const RealType& value )
+                                               const IndexType column,
+                                               const RealType& value )
 {
    this->values.setElement( this->getElementIndex( row, column ), value );
    return true;
@@ -166,11 +188,11 @@ template< typename Real,
           typename Index >
 __cuda_callable__
 bool Dense< Real, Device, Index >::addElementFast( const IndexType row,
-                                                            const IndexType column,
-                                                            const RealType& value,
-                                                            const RealType& thisElementMultiplicator )
+                                                   const IndexType column,
+                                                   const RealType& value,
+                                                   const RealType& thisElementMultiplicator )
 {
-   Assert( row >= 0 && row < this->getRows() &&
+   TNL_ASSERT( row >= 0 && row < this->getRows() &&
               column >= 0 && column < this->getColumns(),
               printf( " row = %d, column = %d, this->getRows = %d, this->getColumns() = %d \n", row, column, this->getRows(), this->getColumns() ) );
    const IndexType elementIndex = this->getElementIndex( row, column );
@@ -210,7 +232,7 @@ bool Dense< Real, Device, Index >::setRowFast( const IndexType row,
                                                         const RealType* values,
                                                         const IndexType elements )
 {
-   Assert( elements <= this->getColumns(),
+   TNL_ASSERT( elements <= this->getColumns(),
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->getColumns() );
    for( IndexType i = 0; i < elements; i++ )
@@ -226,7 +248,7 @@ bool Dense< Real, Device, Index >::setRow( const IndexType row,
                                                     const RealType* values,
                                                     const IndexType elements )
 {
-   Assert( elements <= this->getColumns(),
+   TNL_ASSERT( elements <= this->getColumns(),
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->getColumns() );
    for( IndexType i = 0; i < elements; i++ )
@@ -244,7 +266,7 @@ bool Dense< Real, Device, Index >::addRowFast( const IndexType row,
                                                         const IndexType elements,
                                                         const RealType& thisRowMultiplicator )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    for( IndexType i = 0; i < elements; i++ )
@@ -262,7 +284,7 @@ bool Dense< Real, Device, Index >::addRow( const IndexType row,
                                                     const IndexType elements,
                                                     const RealType& thisRowMultiplicator )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    for( IndexType i = 0; i < elements; i++ )
@@ -279,7 +301,7 @@ __cuda_callable__
 const Real& Dense< Real, Device, Index >::getElementFast( const IndexType row,
                                                             const IndexType column ) const
 {
-   Assert( row >= 0 && row < this->getRows() &&
+   TNL_ASSERT( row >= 0 && row < this->getRows() &&
               column >= 0 && column < this->getColumns(),
               printf( " row = %d, column = %d, this->getRows = %d, this->getColumns() = %d \n", row, column, this->getRows(), this->getColumns() ) );
    return this->values.operator[]( this->getElementIndex( row, column ) );
@@ -367,10 +389,10 @@ template< typename Real,
 void Dense< Real, Device, Index >::vectorProduct( const InVector& inVector,
                                                            OutVector& outVector ) const
 {
-   Assert( this->getColumns() == inVector.getSize(),
+   TNL_ASSERT( this->getColumns() == inVector.getSize(),
             std::cerr << "Matrix columns: " << this->getColumns() << std::endl
                  << "Vector size: " << inVector.getSize() << std::endl );
-   Assert( this->getRows() == outVector.getSize(),
+   TNL_ASSERT( this->getRows() == outVector.getSize(),
                std::cerr << "Matrix rows: " << this->getRows() << std::endl
                     << "Vector size: " << outVector.getSize() << std::endl );
 
@@ -385,7 +407,7 @@ void Dense< Real, Device, Index >::addMatrix( const Matrix& matrix,
                                                        const RealType& matrixMultiplicator,
                                                        const RealType& thisMatrixMultiplicator )
 {
-   Assert( this->getColumns() == matrix.getColumns() &&
+   TNL_ASSERT( this->getColumns() == matrix.getColumns() &&
               this->getRows() == matrix.getRows(),
             std::cerr << "This matrix columns: " << this->getColumns() << std::endl
                  << "This matrix rows: " << this->getRows() << std::endl
@@ -506,7 +528,7 @@ void Dense< Real, Device, Index >::getMatrixProduct( const Matrix1& matrix1,
                                                               const RealType& matrix1Multiplicator,
                                                               const RealType& matrix2Multiplicator )
 {
-   Assert( matrix1.getColumns() == matrix2.getRows() &&
+   TNL_ASSERT( matrix1.getColumns() == matrix2.getRows() &&
               this->getRows() == matrix1.getRows() &&
               this->getColumns() == matrix2.getColumns(),
             std::cerr << "This matrix columns: " << this->getColumns() << std::endl
@@ -742,7 +764,7 @@ template< typename Real,
 void Dense< Real, Device, Index >::getTransposition( const Matrix& matrix,
                                                               const RealType& matrixMultiplicator )
 {
-   Assert( this->getColumns() == matrix.getRows() &&
+   TNL_ASSERT( this->getColumns() == matrix.getRows() &&
               this->getRows() == matrix.getColumns(),
                std::cerr << "This matrix columns: " << this->getColumns() << std::endl
                     << "This matrix rows: " << this->getRows() << std::endl
@@ -818,7 +840,7 @@ void Dense< Real, Device, Index >::getTransposition( const Matrix& matrix,
                                                          gridIdx_x,
                                                          gridIdx_y );
             }
-            checkCudaDevice;
+            TNL_CHECK_CUDA_DEVICE;
          }
       Devices::Cuda::freeFromDevice( this_device );
       Devices::Cuda::freeFromDevice( matrix_device );
@@ -846,6 +868,39 @@ void Dense< Real, Device, Index >::performSORIteration( const Vector& b,
    x[ row ] = ( 1.0 - omega ) * x[ row ] + omega / diagonalValue * ( b[ row ] - sum );
 }
 
+
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+Dense< Real, Device, Index >&
+Dense< Real, Device, Index >::operator=( const Dense& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+Dense< Real, Device, Index >&
+Dense< Real, Device, Index >::operator=( const Dense< Real2, Device2, Index2 >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value,
+                  "unknown device" );
+
+   this->setLike( matrix );
+
+   std::cerr << "Cross-device assignment for the Dense format is not implemented yet." << std::endl;
+   throw 1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -903,7 +958,7 @@ __cuda_callable__
 Index Dense< Real, Device, Index >::getElementIndex( const IndexType row,
                                                               const IndexType column ) const
 {
-   Assert( ( std::is_same< Device, Devices::Host >::value ||
+   TNL_ASSERT( ( std::is_same< Device, Devices::Host >::value ||
           std::is_same< Device, Devices::Cuda >::value ), )
    if( std::is_same< Device, Devices::Host >::value )
       return row * this->columns + column;
diff --git a/src/TNL/Matrices/Ellpack.h b/src/TNL/Matrices/Ellpack.h
index f7d0b9cca03beb9c60e5d5c860e76789d1f97c07..b284f02adb5bd20d7311fc0d4016e20eda0509de 100644
--- a/src/TNL/Matrices/Ellpack.h
+++ b/src/TNL/Matrices/Ellpack.h
@@ -22,12 +22,20 @@ class EllpackDeviceDependentCode;
 template< typename Real, typename Device = Devices::Host, typename Index = int >
 class Ellpack : public Sparse< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class Ellpack;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Sparse< RealType, DeviceType, IndexType >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Sparse< RealType, DeviceType, IndexType >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef typename Sparse< RealType, DeviceType, IndexType >::ValuesVector ValuesVector;
    typedef typename Sparse< RealType, DeviceType, IndexType >::ColumnIndexesVector ColumnIndexesVector;
    typedef Ellpack< Real, Device, Index > ThisType;
@@ -35,6 +43,7 @@ class Ellpack : public Sparse< Real, Device, Index >
    typedef Ellpack< Real, Devices::Cuda, Index > CudaType;
    typedef Sparse< Real, Device, Index > BaseType;
    typedef typename BaseType::MatrixRow MatrixRow;
+   typedef SparseRow< const RealType, const IndexType > ConstMatrixRow;
 
    Ellpack();
 
@@ -42,17 +51,24 @@ class Ellpack : public Sparse< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
-   bool setConstantCompressedRowsLengths( const IndexType& rowLengths );
+   void setConstantCompressedRowLengths( const IndexType& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Ellpack< Real2, Device2, Index2 >& matrix );
+   void setLike( const Ellpack< Real2, Device2, Index2 >& matrix );
 
    void reset();
  
@@ -62,10 +78,6 @@ class Ellpack : public Sparse< Real, Device, Index >
    template< typename Real2, typename Device2, typename Index2 >
    bool operator != ( const Ellpack< Real2, Device2, Index2 >& matrix ) const;
 
-   /*template< typename Matrix >
-   bool copyFrom( const Matrix& matrix,
-                  const CompressedRowsLengthsVector& rowLengths );*/
-
    __cuda_callable__
    bool setElementFast( const IndexType row,
                         const IndexType column,
@@ -128,7 +140,7 @@ class Ellpack : public Sparse< Real, Device, Index >
    MatrixRow getRow( const IndexType rowIndex );
 
    __cuda_callable__
-   const MatrixRow getRow( const IndexType rowIndex ) const;
+   ConstMatrixRow getRow( const IndexType rowIndex ) const;
 
    template< typename Vector >
    __cuda_callable__
@@ -155,6 +167,14 @@ class Ellpack : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   Ellpack& operator=( const Ellpack& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   Ellpack& operator=( const Ellpack< Real2, Device2, Index2 >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -165,9 +185,9 @@ class Ellpack : public Sparse< Real, Device, Index >
 
    void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
-   bool allocateElements();
+   void allocateElements();
 
    IndexType rowLengths, alignedRows;
 
diff --git a/src/TNL/Matrices/Ellpack_impl.h b/src/TNL/Matrices/Ellpack_impl.h
index beab1b135d585893f8f4bbbe3b7a0ef383e8faec..4055515b35e3687a3a01688a95b0858da4b1cbc7 100644
--- a/src/TNL/Matrices/Ellpack_impl.h
+++ b/src/TNL/Matrices/Ellpack_impl.h
@@ -50,10 +50,26 @@ String Ellpack< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                             const IndexType columns )
+String Ellpack< Real, Device, Index >::getSerializationType()
 {
-   Assert( rows > 0 && columns > 0,
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String Ellpack< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void Ellpack< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                    const IndexType columns )
+{
+   TNL_ASSERT( rows > 0 && columns > 0,
               std::cerr << "rows = " << rows
                    << " columns = " << columns << std::endl );
    this->rows = rows;
@@ -62,33 +78,32 @@ bool Ellpack< Real, Device, Index >::setDimensions( const IndexType rows,
       this->alignedRows = roundToMultiple( columns, Devices::Cuda::getWarpSize() );
    else this->alignedRows = rows;
    if( this->rowLengths != 0 )
-      return allocateElements();
-   return true;
+      allocateElements();
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void Ellpack< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
-   Assert( this->getRows() > 0, );
-   Assert( this->getColumns() > 0, );
-   Assert( rowLengths.getSize() > 0, );
+   TNL_ASSERT_GT( this->getRows(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_GT( this->getColumns(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_EQ( this->getRows(), rowLengths.getSize(), "wrong size of the rowLengths vector" );
+
    this->rowLengths = this->maxRowLength = rowLengths.max();
-   return allocateElements();
+   allocateElements();
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::setConstantCompressedRowsLengths( const IndexType& rowLengths )
+void Ellpack< Real, Device, Index >::setConstantCompressedRowLengths( const IndexType& rowLengths )
 {
-   Assert( rowLengths > 0,
+   TNL_ASSERT( rowLengths > 0,
               std::cerr << " rowLengths = " << rowLengths );
    this->rowLengths = rowLengths;
    if( this->rows > 0 )
-      return allocateElements();
-   return true;
+      allocateElements();
 }
 
 template< typename Real,
@@ -99,19 +114,26 @@ Index Ellpack< Real, Device, Index >::getRowLength( const IndexType row ) const
    return this->rowLengths;
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index Ellpack< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
+{
+   return this->rowLengths;
+}
+
 template< typename Real,
           typename Device,
           typename Index >
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool Ellpack< Real, Device, Index >::setLike( const Ellpack< Real2, Device2, Index2 >& matrix )
+void Ellpack< Real, Device, Index >::setLike( const Ellpack< Real2, Device2, Index2 >& matrix )
 {
-   if( ! Sparse< Real, Device, Index >::setLike( matrix ) )
-      return false;
+   Sparse< Real, Device, Index >::setLike( matrix );
    this->rowLengths = matrix.rowLengths;
    this->alignedRows = matrix.alignedRows;
-   return true;
 }
 
 template< typename Real,
@@ -132,7 +154,7 @@ template< typename Real,
              typename Index2 >
 bool Ellpack< Real, Device, Index >::operator == ( const Ellpack< Real2, Device2, Index2 >& matrix ) const
 {
-   Assert( this->getRows() == matrix.getRows() &&
+   TNL_ASSERT( this->getRows() == matrix.getRows() &&
               this->getColumns() == matrix.getColumns(),
               std::cerr << "this->getRows() = " << this->getRows()
                    << " matrix.getRows() = " << matrix.getRows()
@@ -153,16 +175,6 @@ bool Ellpack< Real, Device, Index >::operator != ( const Ellpack< Real2, Device2
    return ! ( ( *this ) == matrix );
 }
 
-/*template< typename Real,
-          typename Device,
-          typename Index >
-   template< typename Matrix >
-bool Ellpack< Real, Device, Index >::copyFrom( const Matrix& matrix,
-                                                        const CompressedRowsLengthsVector& rowLengths )
-{
-   return Matrix< RealType, DeviceType, IndexType >::copyFrom( matrix, rowLengths );
-}*/
-
 template< typename Real,
           typename Device,
           typename Index >
@@ -195,7 +207,7 @@ bool Ellpack< Real, Device, Index > :: addElementFast( const IndexType row,
                                                                 const RealType& thisElementMultiplicator )
 {
    // TODO: return this back when CUDA kernels support std::cerr
-   /*Assert( row >= 0 && row < this->rows &&
+   /*TNL_ASSERT( row >= 0 && row < this->rows &&
               column >= 0 && column <= this->rows,
               std::cerr << " row = " << row
                    << " column = " << column
@@ -455,16 +467,16 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__
-const typename Ellpack< Real, Device, Index >::MatrixRow
+typename Ellpack< Real, Device, Index >::ConstMatrixRow
 Ellpack< Real, Device, Index >::
 getRow( const IndexType rowIndex ) const
 {
    //printf( "this->rowLengths = %d this = %p \n", this->rowLengths, this );
    IndexType rowBegin = DeviceDependentCode::getRowBegin( *this, rowIndex );
-   return MatrixRow( &this->columnIndexes[ rowBegin ],
-                     &this->values[ rowBegin ],
-                     this->rowLengths,
-                     DeviceDependentCode::getElementStep( *this ) );
+   return ConstMatrixRow( &this->columnIndexes[ rowBegin ],
+                          &this->values[ rowBegin ],
+                          this->rowLengths,
+                          DeviceDependentCode::getElementStep( *this ) );
 }
 
 template< typename Real,
@@ -509,7 +521,7 @@ void Ellpack< Real, Device, Index > :: addMatrix( const Ellpack< Real2, Device,
                                                                  const RealType& matrixMultiplicator,
                                                                  const RealType& thisMatrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -521,7 +533,7 @@ template< typename Real,
 void Ellpack< Real, Device, Index >::getTransposition( const Ellpack< Real2, Device, Index2 >& matrix,
                                                                       const RealType& matrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -534,7 +546,7 @@ bool Ellpack< Real, Device, Index > :: performSORIteration( const Vector& b,
                                                                            Vector& x,
                                                                            const RealType& omega ) const
 {
-   Assert( row >=0 && row < this->getRows(),
+   TNL_ASSERT( row >=0 && row < this->getRows(),
               std::cerr << "row = " << row
                    << " this->getRows() = " << this->getRows() << std::endl );
 
@@ -564,17 +576,95 @@ bool Ellpack< Real, Device, Index > :: performSORIteration( const Vector& b,
 }
 
 
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+Ellpack< Real, Device, Index >&
+Ellpack< Real, Device, Index >::operator=( const Ellpack& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->columnIndexes = matrix.columnIndexes;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+Ellpack< Real, Device, Index >&
+Ellpack< Real, Device, Index >::operator=( const Ellpack< Real2, Device2, Index2 >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value,
+                  "unknown device" );
+
+   // setLike does not work here due to different alignment on Cuda and Host
+   this->rowLengths = matrix.rowLengths;
+   this->setDimensions( matrix.getRows(), matrix.getColumns() );
+
+   const int blockSize = 32;
+   const int blocks = roundUpDivision( this->getRows(), blockSize );
+
+   // host -> cuda
+   if( std::is_same< Device, Devices::Cuda >::value ) {
+      typename ValuesVector::HostType tmpValues;
+      typename ColumnIndexesVector::HostType tmpColumnIndexes;
+      tmpValues.setLike( this->values );
+      tmpColumnIndexes.setLike( this->columnIndexes );
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( Index b = 0; b < blocks; b++ ) {
+         const Index offset = b * blockSize;
+         for( Index j = 0; j < rowLengths; j++ )
+            for( Index i = 0; i < blockSize && offset + i < this->getRows(); i++ ) {
+               tmpValues[ offset + j * alignedRows + i ] = matrix.values[ ( offset + i ) * rowLengths + j ];
+               tmpColumnIndexes[ offset + j * alignedRows + i ] = matrix.columnIndexes[ ( offset + i ) * rowLengths + j ];
+            }
+      }
+
+      this->values = tmpValues;
+      this->columnIndexes = tmpColumnIndexes;
+   }
+
+   // cuda -> host
+   if( std::is_same< Device, Devices::Host >::value ) {
+      ValuesVector tmpValues;
+      ColumnIndexesVector tmpColumnIndexes;
+      tmpValues.setLike( matrix.values );
+      tmpColumnIndexes.setLike( matrix.columnIndexes );
+      tmpValues = matrix.values;
+      tmpColumnIndexes = matrix.columnIndexes;
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( Index b = 0; b < blocks; b++ ) {
+         const Index offset = b * rowLengths;
+         for( Index i = 0; i < blockSize && b * blockSize + i < this->getRows(); i++ )
+            for( Index j = 0; j < rowLengths; j++ ) {
+               this->values[ offset + i * rowLengths + j ] = tmpValues[ b * blockSize + j * matrix.alignedRows + i ];
+               this->columnIndexes[ offset + i * rowLengths + j ] = tmpColumnIndexes[ b * blockSize + j * matrix.alignedRows + i ];
+            }
+      }
+   }
+
+   return *this;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
 bool Ellpack< Real, Device, Index >::save( File& file ) const
 {
    if( ! Sparse< Real, Device, Index >::save( file) ) return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file.write< IndexType, Devices::Host, IndexType >( &this->rowLengths, 1 ) ) return false;
-#else
    if( ! file.write( &this->rowLengths ) ) return false;
-#endif
    return true;
 }
 
@@ -584,11 +674,7 @@ template< typename Real,
 bool Ellpack< Real, Device, Index >::load( File& file )
 {
    if( ! Sparse< Real, Device, Index >::load( file) ) return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file.read< IndexType, Devices::Host, IndexType >( &this->rowLengths, 1 ) ) return false;
-#else
    if( ! file.read( &this->rowLengths ) ) return false;
-#endif
    return true;
 }
 
@@ -634,11 +720,9 @@ void Ellpack< Real, Device, Index >::print( std::ostream& str ) const
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::allocateElements()
+void Ellpack< Real, Device, Index >::allocateElements()
 {
-   if( ! Sparse< Real, Device, Index >::allocateMatrixElements( this->alignedRows * this->rowLengths ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::allocateMatrixElements( this->alignedRows * this->rowLengths );
 }
 
 template<>
@@ -706,7 +790,7 @@ template<
 __global__ void EllpackVectorProductCudaKernel(
    const Index rows,
    const Index columns,
-   const Index compressedRowsLengths,
+   const Index compressedRowLengths,
    const Index alignedRows,
    const Index paddingIndex,
    const Index* columnIndexes,
@@ -722,7 +806,7 @@ __global__ void EllpackVectorProductCudaKernel(
    Index el( 0 );
    Real result( 0.0 );
    Index columnIndex;
-   while( el++ < compressedRowsLengths &&
+   while( el++ < compressedRowLengths &&
           ( columnIndex = columnIndexes[ i ] ) < columns &&
           columnIndex != paddingIndex )
    {
@@ -803,12 +887,12 @@ class EllpackDeviceDependentCode< Devices::Cuda >
                   inVector.getData(),
                   outVector.getData(),
                   gridIdx );
-               checkCudaDevice;
+               TNL_CHECK_CUDA_DEVICE;
             }
             //Devices::Cuda::freeFromDevice( kernel_this );
             //Devices::Cuda::freeFromDevice( kernel_inVector );
             //Devices::Cuda::freeFromDevice( kernel_outVector );
-            checkCudaDevice;
+            TNL_CHECK_CUDA_DEVICE;
             cudaThreadSynchronize();
          #endif
  
diff --git a/src/TNL/Matrices/Matrix.h b/src/TNL/Matrices/Matrix.h
index 57e95defa1219fd27eb79b24e954df3a4ee1defa..2af4d0a890c9acf52e98019f23d0aeeb282d77cb 100644
--- a/src/TNL/Matrices/Matrix.h
+++ b/src/TNL/Matrices/Matrix.h
@@ -22,27 +22,26 @@ template< typename Real = double,
           typename Index = int >
 class Matrix : public virtual Object
 {
-   public:
-
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef Containers::Vector< IndexType, DeviceType, IndexType > CompressedRowsLengthsVector;
+   typedef Containers::Vector< IndexType, DeviceType, IndexType > CompressedRowLengthsVector;
    typedef Containers::Vector< RealType, DeviceType, IndexType > ValuesVector;
 
    Matrix();
 
-   virtual bool setDimensions( const IndexType rows,
+   virtual void setDimensions( const IndexType rows,
                                const IndexType columns );
 
-   virtual bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths ) = 0;
+   virtual void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths ) = 0;
 
    virtual IndexType getRowLength( const IndexType row ) const = 0;
 
-   virtual void getCompressedRowsLengths( Containers::Vector< IndexType, DeviceType, IndexType >& rowLengths ) const;
+   virtual void getCompressedRowLengths( Containers::Vector< IndexType, DeviceType, IndexType >& rowLengths ) const;
 
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Matrix< Real2, Device2, Index2 >& matrix );
+   void setLike( const Matrix< Real2, Device2, Index2 >& matrix );
 
    virtual IndexType getNumberOfMatrixElements() const = 0;
 
@@ -85,30 +84,22 @@ class Matrix : public virtual Object
    virtual Real getElement( const IndexType row,
                             const IndexType column ) const = 0;
 
-   Matrix< RealType, DeviceType, IndexType >& operator = ( const Matrix< RealType, DeviceType, IndexType >& );
-
    template< typename Matrix >
    bool operator == ( const Matrix& matrix ) const;
 
    template< typename Matrix >
    bool operator != ( const Matrix& matrix ) const;
 
-   template< typename Matrix >
-   bool copyFrom( const Matrix& matrix,
-                  const CompressedRowsLengthsVector& rowLengths );
-
    virtual bool save( File& file ) const;
 
    virtual bool load( File& file );
 
    virtual void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
    IndexType rows, columns;
 
-   public: // TODO: remove this
-
    ValuesVector values;
 };
 
@@ -123,8 +114,8 @@ template< typename Matrix,
           typename InVector,
           typename OutVector >
 void MatrixVectorProductCuda( const Matrix& matrix,
-                                 const InVector& inVector,
-                                 OutVector& outVector );
+                              const InVector& inVector,
+                              OutVector& outVector );
 
 } // namespace Matrices
 } // namespace TNL
diff --git a/src/TNL/Matrices/MatrixOperations.h b/src/TNL/Matrices/MatrixOperations.h
index 4cecc842596b3cbb0e7913c174d6e6794b159fbd..2c0b8d184841545e3429a1a022a315eb047eb808 100644
--- a/src/TNL/Matrices/MatrixOperations.h
+++ b/src/TNL/Matrices/MatrixOperations.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          MatrixOperations.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 /*
@@ -5,6 +17,7 @@
  * The algorithms should be incorporated into the Matrices::Dense class.
  */
 
+#include <TNL/Exceptions/CudaSupportMissing.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
 #include <TNL/Math.h>
@@ -24,6 +37,8 @@ public:
     *    lda >= m is the leading dimension of two-dimensional array used to store matrix A,
     *    x is a vector of n elements,
     *    y is a vector of m elements.
+    *
+    * It is assumed that n is much smaller than m.
     */
    template< typename RealType,
              typename IndexType >
@@ -37,31 +52,179 @@ public:
          const RealType& beta,
          RealType* y )
    {
-      Assert( m <= lda, );
+      TNL_ASSERT_GT( m, 0, "m must be positive" );
+      TNL_ASSERT_GT( n, 0, "n must be positive" );
+      TNL_ASSERT_GE( lda, m, "lda must be at least m" );
 
-      if( beta != 0.0 ) {
-#ifdef HAVE_OPENMP
-#pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() )
-#endif
-         for( IndexType j = 0; j < m; j++ ) {
-            RealType tmp = 0.0;
-            for( int k = 0; k < n; k++ )
-               tmp += A[ j + k * lda ] * x[ k ];
-            y[ j ] = alpha * tmp + beta * y[ j ];
+      RealType alphax[ n ];
+      for( IndexType k = 0; k < n; k++ )
+         alphax[ k ] = alpha * x[ k ];
+
+      if( n == 1 ) {
+         if( beta != 0.0 ) {
+            #ifdef HAVE_OPENMP
+            #pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() )
+            #endif
+            for( IndexType j = 0; j < m; j++ )
+               y[ j ] = A[ j ] * alphax[ 0 ] + beta * y[ j ];
+         }
+         else {
+            // the vector y might be uninitialized, and 0.0 * NaN = NaN
+            #ifdef HAVE_OPENMP
+            #pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() )
+            #endif
+            for( IndexType j = 0; j < m; j++ )
+               y[ j ] = A[ j ] * alphax[ 0 ];
          }
       }
       else {
-         // the vector y might be uninitialized, and 0.0 * NaN = NaN
-#ifdef HAVE_OPENMP
-#pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() )
-#endif
-         for( IndexType j = 0; j < m; j++ ) {
-            RealType tmp = 0.0;
-            for( int k = 0; k < n; k++ )
-               tmp += A[ j + k * lda ] * x[ k ];
-            y[ j ] = alpha * tmp;
+         // the matrix A should be accessed column-wise so we split the work into small
+         // blocks and each block process by columns, either parallelly or serially
+         constexpr int block_size = 128;
+         const int blocks = m / block_size;
+
+         #ifdef HAVE_OPENMP
+         #pragma omp parallel if( TNL::Devices::Host::isOMPEnabled() && blocks >= 2 )
+         #endif
+         {
+            RealType aux[ block_size ];
+
+            #ifdef HAVE_OPENMP
+            #pragma omp for nowait
+            #endif
+            for( int b = 0; b < blocks; b++ ) {
+               const int block_offset = b * block_size;
+
+               // initialize array for thread-local results
+               for( int j = 0; j < block_size; j++ )
+                  aux[ j ] = 0.0;
+
+               // compute aux = A * alphax
+               for( int k = 0; k < n; k++ ) {
+                  const int offset = block_offset + k * lda;
+                  for( int j = 0; j < block_size; j++ )
+                     aux[ j ] += A[ offset + j ] * alphax[ k ];
+               }
+
+               // write result: y = aux + beta * y
+               if( beta != 0.0 ) {
+                  for( int j = 0; j < block_size; j++ )
+                     y[ block_offset + j ] = aux[ j ] + beta * y[ block_offset + j ];
+               }
+               else {
+                  // the vector y might be uninitialized, and 0.0 * NaN = NaN
+                  for( IndexType j = 0; j < block_size; j++ )
+                     y[ block_offset + j ] = aux[ j ];
+               }
+            }
+
+            // the first thread that reaches here processes the last, incomplete block
+            #ifdef HAVE_OPENMP
+            #pragma omp single nowait
+            #endif
+            {
+               // TODO: unlike the complete blocks, the tail is traversed row-wise
+               if( beta != 0.0 ) {
+                  for( IndexType j = blocks * block_size; j < m; j++ ) {
+                     RealType tmp = 0.0;
+                     for( int k = 0; k < n; k++ )
+                        tmp += A[ j + k * lda ] * alphax[ k ];
+                     y[ j ] = tmp + beta * y[ j ];
+                  }
+               }
+               else {
+                  // the vector y might be uninitialized, and 0.0 * NaN = NaN
+                  for( IndexType j = blocks * block_size; j < m; j++ ) {
+                     RealType tmp = 0.0;
+                     for( int k = 0; k < n; k++ )
+                        tmp += A[ j + k * lda ] * alphax[ k ];
+                     y[ j ] = tmp;
+                  }
+               }
+            }
          }
       }
+
+   }
+
+   /*
+    * This function performs the matrix-matrix addition
+    *    C = alpha * A + beta * B
+    * where:
+    *    alpha and beta are scalars,
+    *    A, B, C are (m by n) matrices stored in column-major format on Devices::Cuda,
+    *    lda, ldb, ldc (all >= m) are the leading dimensions of matrices A, B, C,
+    *    respectively.
+    *
+    * It is assumed that n is much smaller than m.
+    */
+   template< typename RealType,
+             typename IndexType >
+   static void
+   geam( const IndexType& m,
+         const IndexType& n,
+         const RealType& alpha,
+         const RealType* A,
+         const IndexType& lda,
+         const RealType& beta,
+         const RealType* B,
+         const IndexType& ldb,
+         RealType* C,
+         const IndexType& ldc )
+   {
+      TNL_ASSERT_GT( m, 0, "m must be positive" );
+      TNL_ASSERT_GT( n, 0, "n must be positive" );
+      TNL_ASSERT_GE( lda, m, "lda must be at least m" );
+      TNL_ASSERT_GE( ldb, m, "lda must be at least m" );
+      TNL_ASSERT_GE( ldc, m, "lda must be at least m" );
+
+      if( n == 1 ) {
+         #ifdef HAVE_OPENMP
+         #pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() )
+         #endif
+         for( IndexType j = 0; j < m; j++ )
+            C[ j ] = alpha * A[ j ] + beta * B[ j ];
+      }
+      else {
+         // all matrices should be accessed column-wise so we split the work into small
+         // blocks and each block process by columns, either parallelly or serially
+         constexpr int block_size = 128;
+         const int blocks = m / block_size;
+
+         #ifdef HAVE_OPENMP
+         #pragma omp parallel if( TNL::Devices::Host::isOMPEnabled() && blocks >= 2 )
+         #endif
+         {
+            #ifdef HAVE_OPENMP
+            #pragma omp for nowait
+            #endif
+            for( int b = 0; b < blocks; b++ ) {
+               const int block_offset = b * block_size;
+               for( IndexType j = 0; j < n; j++ ) {
+                  const IndexType offset_A = j * lda + block_offset;
+                  const IndexType offset_B = j * ldb + block_offset;
+                  const IndexType offset_C = j * ldc + block_offset;
+                  for( int i = 0; i < block_size; i++ )
+                     C[ offset_C + i ] = alpha * A[ offset_A + i ] + beta * B[ offset_B + i ];
+               }
+            }
+
+            // the first thread that reaches here processes the last, incomplete block
+            #ifdef HAVE_OPENMP
+            #pragma omp single nowait
+            #endif
+            {
+               for( IndexType j = 0; j < n; j++ ) {
+                  const IndexType offset_A = j * lda;
+                  const IndexType offset_B = j * ldb;
+                  const IndexType offset_C = j * ldc;
+                  for( IndexType i = blocks * block_size; i < m; i++ )
+                     C[ offset_C + i ] = alpha * A[ offset_A + i ] + beta * B[ offset_B + i ];
+               }
+            }
+         }
+      }
+
    }
 };
 
@@ -69,12 +232,6 @@ public:
 // CUDA kernels
 #ifdef HAVE_CUDA
 
-#if (__CUDA_ARCH__ >= 300 )
-   static constexpr int Gemv_minBlocksPerMultiprocessor = 8;
-#else
-   static constexpr int Gemv_minBlocksPerMultiprocessor = 4;
-#endif
-
 template< typename RealType,
           typename IndexType >
 __global__ void
@@ -90,19 +247,10 @@ GemvCudaKernel( const IndexType m,
    IndexType elementIdx = blockIdx.x * blockDim.x + threadIdx.x;
    const IndexType gridSize = blockDim.x * gridDim.x;
 
-   // NOTE: Plain declaration such as
-   //          extern __shared__ RealType shx[];
-   //       won't work because extern variables must be declared exactly once.
-   //       In templated functions we need to have same variable name with
-   //       different type, which causes the conflict. In CUDA samples they
-   //       solve it using template specialization via classes, but using char
-   //       as the base type and reinterpret_cast works too.
-   //       See http://stackoverflow.com/a/19339004/4180822
-   extern __shared__ __align__ ( 8 ) char __sdata[];
-   RealType* shx = reinterpret_cast< RealType* >( __sdata );
+   RealType* shx = Devices::Cuda::getSharedMemory< RealType >();
 
    if( threadIdx.x < n )
-      shx[ threadIdx.x ] = x[ threadIdx.x ];
+      shx[ threadIdx.x ] = alpha * x[ threadIdx.x ];
    __syncthreads();
 
    if( beta != 0.0 ) {
@@ -110,7 +258,7 @@ GemvCudaKernel( const IndexType m,
          RealType tmp = 0.0;
          for( IndexType k = 0; k < n; k++ )
             tmp += A[ elementIdx + k * lda ] * shx[ k ];
-         y[ elementIdx ] = alpha * tmp + beta * y[ elementIdx ];
+         y[ elementIdx ] = tmp + beta * y[ elementIdx ];
          elementIdx += gridSize;
       }
    }
@@ -120,11 +268,39 @@ GemvCudaKernel( const IndexType m,
          RealType tmp = 0.0;
          for( IndexType k = 0; k < n; k++ )
             tmp += A[ elementIdx + k * lda ] * shx[ k ];
-         y[ elementIdx ] = alpha * tmp;
+         y[ elementIdx ] = tmp;
          elementIdx += gridSize;
       }
    }
 }
+
+template< typename RealType,
+          typename IndexType >
+__global__ void
+GeamCudaKernel( const IndexType m,
+                const IndexType n,
+                const RealType alpha,
+                const RealType* A,
+                const IndexType lda,
+                const RealType beta,
+                const RealType* B,
+                const IndexType ldb,
+                RealType* C,
+                const IndexType ldc )
+{
+   IndexType x = blockIdx.x * blockDim.x + threadIdx.x;
+   const IndexType gridSizeX = blockDim.x * gridDim.x;
+   const IndexType y = blockIdx.y * blockDim.y + threadIdx.y;
+   const IndexType offset_A = y * lda;
+   const IndexType offset_B = y * ldb;
+   const IndexType offset_C = y * ldc;
+
+   if( y < n )
+      while( x < m ) {
+         C[ x + offset_C ] = alpha * A[ x + offset_A ] + beta * B[ x + offset_B ];
+         x += gridSizeX;
+      }
+}
 #endif
 
 // specialization for CUDA
@@ -141,6 +317,8 @@ public:
     *    lda >= m is the leading dimension of two-dimensional array used to store matrix A,
     *    x is a vector of n elements, stored on Devices::Host,
     *    y is a vector of m elements, stored on Devices::Cuda.
+    *
+    * It is assumed that n is much smaller than m.
     */
    template< typename RealType,
              typename IndexType >
@@ -154,29 +332,86 @@ public:
          const RealType& beta,
          RealType* y )
    {
-      Assert( m <= lda, );
-      Assert( n <= 256,
+      TNL_ASSERT( m <= lda, );
+      TNL_ASSERT( n <= 256,
               std::cerr << "The gemv kernel is optimized only for small 'n' and assumes that n <= 256." << std::endl; );
 
 #ifdef HAVE_CUDA
       Containers::Vector< RealType, Devices::Cuda, IndexType > xDevice;
       xDevice.setSize( n );
-      if( ! Containers::ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< RealType, RealType, IndexType >( xDevice.getData(), x, n ) )
+      if( ! Containers::Algorithms::ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< RealType, RealType, IndexType >( xDevice.getData(), x, n ) )
          throw 1;
 
-      dim3 blockSize( 256 );
-      dim3 gridSize;
-      const IndexType desGridSize = 4 * Gemv_minBlocksPerMultiprocessor
-                                      * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+      // desGridSize = blocksPerMultiprocessor * numberOfMultiprocessors
+      const int desGridSize = 32 * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+      dim3 blockSize, gridSize;
+      blockSize.x = 256;
       gridSize.x = min( desGridSize, Devices::Cuda::getNumberOfBlocks( m, blockSize.x ) );
 
       GemvCudaKernel<<< gridSize, blockSize, n * sizeof( RealType ) >>>(
             m, n,
             alpha, A, lda,
             xDevice.getData(), beta, y );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
+#else
+      throw Exceptions::CudaSupportMissing();
+#endif
+   }
+
+   /*
+    * This function performs the matrix-matrix addition
+    *    C = alpha * A + beta * B
+    * where:
+    *    alpha and beta are scalars,
+    *    A, B, C are (m by n) matrices stored in column-major format on Devices::Cuda,
+    *    lda, ldb, ldc (all >= m) are the leading dimensions of matrices A, B, C,
+    *    respectively.
+    *
+    * It is assumed that n is much smaller than m.
+    */
+   template< typename RealType,
+             typename IndexType >
+   static void
+   geam( const IndexType& m,
+         const IndexType& n,
+         const RealType& alpha,
+         const RealType* A,
+         const IndexType& lda,
+         const RealType& beta,
+         const RealType* B,
+         const IndexType& ldb,
+         RealType* C,
+         const IndexType& ldc )
+   {
+      TNL_ASSERT_GT( m, 0, "m must be positive" );
+      TNL_ASSERT_GT( n, 0, "n must be positive" );
+      TNL_ASSERT_GE( lda, m, "lda must be at least m" );
+      TNL_ASSERT_GE( ldb, m, "lda must be at least m" );
+      TNL_ASSERT_GE( ldc, m, "lda must be at least m" );
+
+#ifdef HAVE_CUDA
+      dim3 blockSize, gridSize;
+
+      // max 16 columns of threads
+      blockSize.y = min( n, 16 );
+      // max 256 threads per block, power of 2
+      blockSize.x = 256;
+      while( blockSize.x * blockSize.y > 256 )
+         blockSize.x /= 2;
+
+      // desGridSize = blocksPerMultiprocessor * numberOfMultiprocessors
+      const int desGridSize = 32 * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+      gridSize.x = min( desGridSize, Devices::Cuda::getNumberOfBlocks( m, blockSize.x ) );
+      gridSize.y = Devices::Cuda::getNumberOfBlocks( n, blockSize.y );
+
+      GeamCudaKernel<<< gridSize, blockSize >>>(
+            m, n,
+            alpha, A, lda,
+            beta, B, ldb,
+            C, ldc );
+      TNL_CHECK_CUDA_DEVICE;
 #else
-      CudaSupportMissingMessage;
+      throw Exceptions::CudaSupportMissing();
 #endif
    }
 };
diff --git a/src/TNL/Matrices/MatrixReader.h b/src/TNL/Matrices/MatrixReader.h
index 1bcb88842a65455b9e93bf4620af9a9748cbdbfb..fb9788b5fbd736b8448660f1f8cd20a5ec44a7a9 100644
--- a/src/TNL/Matrices/MatrixReader.h
+++ b/src/TNL/Matrices/MatrixReader.h
@@ -39,7 +39,7 @@ class MatrixReader
 
    static bool readMtxFileHostMatrix( std::istream& file,
                                       Matrix& matrix,
-                                      typename Matrix::CompressedRowsLengthsVector& rowLengths,
+                                      typename Matrix::CompressedRowLengthsVector& rowLengths,
                                       bool verbose );
 
 
@@ -63,7 +63,7 @@ class MatrixReader
                               bool& symmetricMatrix,
                               bool verbose );
 
-   static bool computeCompressedRowsLengthsFromMtxFile( std::istream& file,
+   static bool computeCompressedRowLengthsFromMtxFile( std::istream& file,
                                              Containers::Vector< int, Devices::Host, int >& rowLengths,
                                              const int columns,
                                              const int rows,
diff --git a/src/TNL/Matrices/MatrixReader_impl.h b/src/TNL/Matrices/MatrixReader_impl.h
index f7ada94abcdd9d7d7867604f38731f32b59cb7bb..f768d748cd62dd5d01923254a5e246c8171b79d1 100644
--- a/src/TNL/Matrices/MatrixReader_impl.h
+++ b/src/TNL/Matrices/MatrixReader_impl.h
@@ -11,10 +11,11 @@
 #pragma once
 
 #include <iomanip>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/String.h>
 #include <TNL/Containers/Vector.h>
 #include <TNL/Timer.h>
+#include <TNL/Matrices/MatrixReader.h>
 
 namespace TNL {
 namespace Matrices {   
@@ -45,7 +46,7 @@ bool MatrixReader< Matrix >::readMtxFile( std::istream& file,
 template< typename Matrix >
 bool MatrixReader< Matrix >::readMtxFileHostMatrix( std::istream& file,
                                                        Matrix& matrix,
-                                                       typename Matrix::CompressedRowsLengthsVector& rowLengths,
+                                                       typename Matrix::CompressedRowLengthsVector& rowLengths,
                                                        bool verbose )
 {
    IndexType rows, columns;
@@ -55,18 +56,13 @@ bool MatrixReader< Matrix >::readMtxFileHostMatrix( std::istream& file,
       return false;
 
 
-   if( ! matrix.setDimensions( rows, columns ) ||
-       ! rowLengths.setSize( rows ) )
-   {
-      std::cerr << "Not enough memory to allocate the sparse or the full matrix for testing." << std::endl;
-      return false;
-   }
+   matrix.setDimensions( rows, columns );
+   rowLengths.setSize( rows );
 
-   if( ! computeCompressedRowsLengthsFromMtxFile( file, rowLengths, columns, rows, symmetricMatrix, verbose ) )
+   if( ! computeCompressedRowLengthsFromMtxFile( file, rowLengths, columns, rows, symmetricMatrix, verbose ) )
       return false;
 
-   if( ! matrix.setCompressedRowsLengths( rowLengths ) )
-      return false;
+   matrix.setCompressedRowLengths( rowLengths );
 
    if( ! readMatrixElementsFromMtxFile( file, matrix, symmetricMatrix, verbose ) )
       return false;
@@ -162,8 +158,8 @@ template< typename Matrix >
 bool MatrixReader< Matrix >::checkMtxHeader( const String& header,
                                                 bool& symmetric )
 {
-   List< String > parsedLine;
-   header.parse( parsedLine );
+   Containers::List< String > parsedLine;
+   header.split( parsedLine );
    if( parsedLine.getSize() < 5 )
       return false;
    if( parsedLine[ 0 ] != "%%MatrixMarket" )
@@ -208,7 +204,7 @@ bool MatrixReader< Matrix >::readMtxHeader( std::istream& file,
    file.seekg( 0, std::ios::beg );
    String line;
    bool headerParsed( false );
-   List< String > parsedLine;
+   Containers::List< String > parsedLine;
    while( true )
    {
       line.getLine( file );
@@ -230,7 +226,7 @@ bool MatrixReader< Matrix >::readMtxHeader( std::istream& file,
       }
 
       parsedLine.reset();
-      line. parse( parsedLine );
+      line.split( parsedLine );
       if( parsedLine. getSize() != 3 )
       {
          std::cerr << "Wrong number of parameters in the matrix header." << std::endl;
@@ -252,7 +248,7 @@ bool MatrixReader< Matrix >::readMtxHeader( std::istream& file,
 }
 
 template< typename Matrix >
-bool MatrixReader< Matrix >::computeCompressedRowsLengthsFromMtxFile( std::istream& file,
+bool MatrixReader< Matrix >::computeCompressedRowLengthsFromMtxFile( std::istream& file,
                                                               Containers::Vector< int, Devices::Host, int >& rowLengths,
                                                               const int columns,
                                                               const int rows,
@@ -364,8 +360,8 @@ bool MatrixReader< Matrix >::parseMtxLineWithElement( const String& line,
                                                          IndexType& column,
                                                          RealType& value )
 {
-   List< String > parsedLine;
-   line.parse( parsedLine );
+   Containers::List< String > parsedLine;
+   line.split( parsedLine );
    if( parsedLine.getSize() != 3 )
    {
       std::cerr << "Wrong number of parameters in the matrix row at line:" << line << std::endl;
@@ -387,7 +383,7 @@ class MatrixReaderDeviceDependentCode< Devices::Host >
                             Matrix& matrix,
                             bool verbose )
    {
-      typename Matrix::CompressedRowsLengthsVector rowLengths;
+      typename Matrix::CompressedRowLengthsVector rowLengths;
       return MatrixReader< Matrix >::readMtxFileHostMatrix( file, matrix, rowLengths, verbose );
    }
 };
@@ -403,18 +399,14 @@ class MatrixReaderDeviceDependentCode< Devices::Cuda >
                             bool verbose )
    {
       typedef typename Matrix::HostType HostMatrixType;
-      typedef typename HostMatrixType::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+      typedef typename HostMatrixType::CompressedRowLengthsVector CompressedRowLengthsVector;
 
       HostMatrixType hostMatrix;
-      CompressedRowsLengthsVector rowLengthsVector;
+      CompressedRowLengthsVector rowLengthsVector;
       if( ! MatrixReader< HostMatrixType >::readMtxFileHostMatrix( file, hostMatrix, rowLengthsVector, verbose ) )
          return false;
 
-      typename Matrix::CompressedRowsLengthsVector cudaCompressedRowsLengthsVector;
-      cudaCompressedRowsLengthsVector.setLike( rowLengthsVector );
-      cudaCompressedRowsLengthsVector = rowLengthsVector;
-      if( ! matrix.copyFrom( hostMatrix, cudaCompressedRowsLengthsVector ) )
-         return false;
+      matrix = hostMatrix;
       return true;
    }
 };
diff --git a/src/TNL/Matrices/MatrixSetter.h b/src/TNL/Matrices/MatrixSetter.h
index 8eae6671851112a2fb22ad19611437d59a030377..8dd15f6a75c4079c20f6801168c4a0ec81da12be 100644
--- a/src/TNL/Matrices/MatrixSetter.h
+++ b/src/TNL/Matrices/MatrixSetter.h
@@ -15,22 +15,22 @@ namespace Matrices {
 
 template< typename DifferentialOperator,
           typename BoundaryConditions,
-          typename CompressedRowsLengthsVector >
+          typename CompressedRowLengthsVector >
 class MatrixSetterTraversalUserData
 {
    public:
       
-      typedef typename CompressedRowsLengthsVector::DeviceType DeviceType;
+      typedef typename CompressedRowLengthsVector::DeviceType DeviceType;
 
       const DifferentialOperator* differentialOperator;
 
       const BoundaryConditions* boundaryConditions;
 
-      CompressedRowsLengthsVector* rowLengths;
+      CompressedRowLengthsVector* rowLengths;
 
       MatrixSetterTraversalUserData( const DifferentialOperator* differentialOperator,
                                      const BoundaryConditions* boundaryConditions,
-                                     CompressedRowsLengthsVector* rowLengths )
+                                     CompressedRowLengthsVector* rowLengths )
       : differentialOperator( differentialOperator ),
         boundaryConditions( boundaryConditions ),
         rowLengths( rowLengths )
@@ -41,26 +41,26 @@ class MatrixSetterTraversalUserData
 template< typename Mesh,
           typename DifferentialOperator,
           typename BoundaryConditions,
-          typename CompressedRowsLengthsVector >
+          typename CompressedRowLengthsVector >
 class MatrixSetter
 {
    public:
    typedef Mesh MeshType;
    typedef SharedPointer< MeshType > MeshPointer;
    typedef typename MeshType::DeviceType DeviceType;
-   typedef typename CompressedRowsLengthsVector::RealType IndexType;
+   typedef typename CompressedRowLengthsVector::RealType IndexType;
    typedef MatrixSetterTraversalUserData< DifferentialOperator,
                                           BoundaryConditions,
-                                          CompressedRowsLengthsVector > TraversalUserData;
+                                          CompressedRowLengthsVector > TraversalUserData;
    typedef SharedPointer< DifferentialOperator, DeviceType > DifferentialOperatorPointer;
    typedef SharedPointer< BoundaryConditions, DeviceType > BoundaryConditionsPointer;
-   typedef SharedPointer< CompressedRowsLengthsVector, DeviceType > CompressedRowsLengthsVectorPointer;
+   typedef SharedPointer< CompressedRowLengthsVector, DeviceType > CompressedRowLengthsVectorPointer;
 
    template< typename EntityType >
-   void getCompressedRowsLengths( const MeshPointer& meshPointer,
+   void getCompressedRowLengths( const MeshPointer& meshPointer,
                                   const DifferentialOperatorPointer& differentialOperatorPointer,
                                   const BoundaryConditionsPointer& boundaryConditionsPointer,
-                                  CompressedRowsLengthsVectorPointer& rowLengthsPointer ) const;
+                                  CompressedRowLengthsVectorPointer& rowLengthsPointer ) const;
 
    class TraversalBoundaryEntitiesProcessor
    {
@@ -97,32 +97,32 @@ class MatrixSetter
 };
 
 /*
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename DifferentialOperator,
           typename BoundaryConditions,
-          typename CompressedRowsLengthsVector >
-class MatrixSetter< Meshes::Grid< Dimensions, Real, Device, Index >,
+          typename CompressedRowLengthsVector >
+class MatrixSetter< Meshes::Grid< Dimension, Real, Device, Index >,
                        DifferentialOperator,
                        BoundaryConditions,
-                       CompressedRowsLengthsVector >
+                       CompressedRowLengthsVector >
 {
    public:
-   typedef Meshes::Grid< Dimensions, Real, Device, Index > MeshType;
+   typedef Meshes::Grid< Dimension, Real, Device, Index > MeshType;
    typedef typename MeshType::DeviceType DeviceType;
-   typedef typename CompressedRowsLengthsVector::RealType IndexType;
+   typedef typename CompressedRowLengthsVector::RealType IndexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
    typedef MatrixSetterTraversalUserData< DifferentialOperator,
                                              BoundaryConditions,
-                                             CompressedRowsLengthsVector > TraversalUserData;
+                                             CompressedRowLengthsVector > TraversalUserData;
 
    template< typename EntityType >
-   void getCompressedRowsLengths( const MeshType& mesh,
+   void getCompressedRowLengths( const MeshType& mesh,
                        const DifferentialOperator& differentialOperator,
                        const BoundaryConditions& boundaryConditions,
-                       CompressedRowsLengthsVector& rowLengths ) const;
+                       CompressedRowLengthsVector& rowLengths ) const;
 
    class TraversalBoundaryEntitiesProcessor
    {
diff --git a/src/TNL/Matrices/MatrixSetter_impl.h b/src/TNL/Matrices/MatrixSetter_impl.h
index d67feadb9ca01fce69089e7b66d180ee88cc8ecf..98f39be7087c890f29edd8ce1e3d4777cb875479 100644
--- a/src/TNL/Matrices/MatrixSetter_impl.h
+++ b/src/TNL/Matrices/MatrixSetter_impl.h
@@ -18,14 +18,14 @@ namespace Matrices {
 template< typename Mesh,
           typename DifferentialOperator,
           typename BoundaryConditions,
-          typename CompressedRowsLengthsVector >
+          typename CompressedRowLengthsVector >
    template< typename EntityType >
 void
-MatrixSetter< Mesh, DifferentialOperator, BoundaryConditions, CompressedRowsLengthsVector >::
-getCompressedRowsLengths( const MeshPointer& meshPointer,
+MatrixSetter< Mesh, DifferentialOperator, BoundaryConditions, CompressedRowLengthsVector >::
+getCompressedRowLengths( const MeshPointer& meshPointer,
                           const DifferentialOperatorPointer& differentialOperatorPointer,
                           const BoundaryConditionsPointer& boundaryConditionsPointer,
-                          CompressedRowsLengthsVectorPointer& rowLengthsPointer ) const
+                          CompressedRowLengthsVectorPointer& rowLengthsPointer ) const
 {
    {
       SharedPointer< TraversalUserData, DeviceType >
diff --git a/src/TNL/Matrices/MatrixWriter.h b/src/TNL/Matrices/MatrixWriter.h
index 5d2be313a4b900272acc3382b54fd35f2ad24572..634a3437b9e6da626a1e1ae47930126c21e2cf0a 100644
--- a/src/TNL/Matrices/MatrixWriter.h
+++ b/src/TNL/Matrices/MatrixWriter.h
@@ -11,6 +11,7 @@
 #pragma once
 
 #include <ostream>
+#include <iostream>
 
 namespace TNL {
 namespace Matrices {   
@@ -23,26 +24,27 @@ class MatrixWriter
    typedef typename Matrix::IndexType IndexType;
    typedef typename Matrix::RealType RealType;
 
-   static bool writeToGnuplot( std::ostream str,
+   static bool writeToGnuplot( std::ostream& str,
                                const Matrix& matrix,
                                bool verbose = false );
 
-   static bool writeToEps( std::ostream str,
+   static bool writeToEps( std::ostream& str,
                            const Matrix& matrix,
                            bool verbose = false );
 
    protected:
 
-   static bool writeEpsHeader( std::ostream str,
+   static bool writeEpsHeader( std::ostream& str,
                                const Matrix& matrix,
                                const int elementSize );
 
-   static bool writeEpsBody( std::ostream str,
+   static bool writeEpsBody( std::ostream& str,
                              const Matrix& matrix,
-                             const int elementSize );
-
-
+                             const int elementSize,
+                             bool verbose );
 };
 
 } // namespace Matrices
 } // namespace TNL
+
+#include <TNL/Matrices/MatrixWriter_impl.h>
diff --git a/src/TNL/Matrices/MatrixWriter_impl.h b/src/TNL/Matrices/MatrixWriter_impl.h
index 9f36993251f073ad99ecb1e8dc2166cd811ea276..40368d0dd9fc157ff90ee0766add1cb64f2acca7 100644
--- a/src/TNL/Matrices/MatrixWriter_impl.h
+++ b/src/TNL/Matrices/MatrixWriter_impl.h
@@ -10,21 +10,23 @@
 
 #pragma once
 
+#include <TNL/Matrices/MatrixWriter.h>
+
 namespace TNL {
 namespace Matrices {   
 
 template< typename Matrix >
-bool MatrixWriter< Matrix >::writeToGnuplot( std::ostream str,
-                                                const Matrix& matrix,
-                                                bool verbose )
+bool MatrixWriter< Matrix >::writeToGnuplot( std::ostream& str,
+                                             const Matrix& matrix,
+                                             bool verbose )
 {
    for( IndexType row = 0; row < matrix.getRows(); row ++ )
    {
       for( IndexType column = 0; column < matrix.getColumns(); column ++ )
       {
-         RealType elementValue = maytrix.getElement( row, column );
+         RealType elementValue = matrix.getElement( row, column );
          if(  elementValue != ( RealType ) 0.0 )
-            str << column << " " << getSize() - row << " " << elementValue << std::endl;
+            str << column << " " << row << " " << elementValue << "\n";
       }
       if( verbose )
         std::cout << "Drawing the row " << row << "      \r" << std::flush;
@@ -35,9 +37,9 @@ bool MatrixWriter< Matrix >::writeToGnuplot( std::ostream str,
 }
 
 template< typename Matrix >
-bool MatrixWriter< Matrix >::writeToEps( std::ostream str,
-                                            const Matrix& matrix,
-                                            bool verbose )
+bool MatrixWriter< Matrix >::writeToEps( std::ostream& str,
+                                         const Matrix& matrix,
+                                         bool verbose )
 {
    const int elementSize = 10;
    if( ! writeEpsHeader( str, matrix, elementSize ) )
@@ -54,9 +56,9 @@ bool MatrixWriter< Matrix >::writeToEps( std::ostream str,
 }
 
 template< typename Matrix >
-bool MatrixWriter< Matrix >::writeEpsHeader( std::ostream str,
-                                                const Marix& matrix,
-                                                const int elementSize )
+bool MatrixWriter< Matrix >::writeEpsHeader( std::ostream& str,
+                                             const Matrix& matrix,
+                                             const int elementSize )
 {
    const double scale = elementSize * max( matrix.getRows(), matrix.getColumns() );
    str << "%!PS-Adobe-2.0 EPSF-2.0" << std::endl;
@@ -69,21 +71,22 @@ bool MatrixWriter< Matrix >::writeEpsHeader( std::ostream str,
 }
 
 template< typename Matrix >
-bool MatrixWriter< Matrix >::writeEpsBody( std::ostream str,
-                                              const Marix& matrix,
-                                              const int elementSize )
+bool MatrixWriter< Matrix >::writeEpsBody( std::ostream& str,
+                                           const Matrix& matrix,
+                                           const int elementSize,
+                                           bool verbose )
 {
    IndexType lastRow( 0 ), lastColumn( 0 );
-   for( IndexType row = 0; row < getSize(); row ++ )
+   for( IndexType row = 0; row < matrix.getRows(); row ++ )
    {
-      for( IndexType column = 0; column < getSize(); column ++ )
+      for( IndexType column = 0; column < matrix.getColumns(); column ++ )
       {
          RealType elementValue = getElement( row, column );
          if( elementValue != ( RealType ) 0.0 )
          {
             str << ( column - lastColumn ) * elementSize
                 << " " << -( row - lastRow ) * elementSize
-                << " translate newpath 0 0 " << elementSize << " " << elementSize << " rectstroke" << std::endl;
+                << " translate newpath 0 0 " << elementSize << " " << elementSize << " rectstroke\n";
             lastColumn = column;
             lastRow = row;
          }
diff --git a/src/TNL/Matrices/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h
index f4dc2a12d997e2eac4abb8d893b437d5e5cf08b0..45593b1552dd501e113b1327e1c33e5bb73a3d16 100644
--- a/src/TNL/Matrices/Matrix_impl.h
+++ b/src/TNL/Matrices/Matrix_impl.h
@@ -28,20 +28,19 @@ Matrix< Real, Device, Index >::Matrix()
 template< typename Real,
           typename Device,
           typename Index >
- bool Matrix< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                       const IndexType columns )
+void Matrix< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                   const IndexType columns )
 {
-   Assert( rows > 0 && columns > 0,
-            std::cerr << " rows = " << rows << " columns = " << columns );
+   TNL_ASSERT( rows > 0 && columns > 0,
+               std::cerr << " rows = " << rows << " columns = " << columns );
    this->rows = rows;
    this->columns = columns;
-   return true;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void Matrix< Real, Device, Index >::getCompressedRowsLengths( Containers::Vector< IndexType, DeviceType, IndexType >& rowLengths ) const
+void Matrix< Real, Device, Index >::getCompressedRowLengths( Containers::Vector< IndexType, DeviceType, IndexType >& rowLengths ) const
 {
    rowLengths.setSize( this->getRows() );
    for( IndexType row = 0; row < this->getRows(); row++ )
@@ -54,9 +53,9 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool Matrix< Real, Device, Index >::setLike( const Matrix< Real2, Device2, Index2 >& matrix )
+void Matrix< Real, Device, Index >::setLike( const Matrix< Real2, Device2, Index2 >& matrix )
 {
-   return setDimensions( matrix.getRows(), matrix.getColumns() );
+   setDimensions( matrix.getRows(), matrix.getColumns() );
 }
 
 template< typename Real,
@@ -86,63 +85,6 @@ void Matrix< Real, Device, Index >::reset()
    this->columns = 0;
 }
 
-template< typename Real,
-          typename Device,
-          typename Index >
-   template< typename MatrixT >
-bool Matrix< Real, Device, Index >::copyFrom( const MatrixT& matrix,
-                                              const CompressedRowsLengthsVector& rowLengths )
-{
-   /*tnlStaticAssert( DeviceType::DeviceType == Devices::HostDevice, );
-   tnlStaticAssert( DeviceType::DeviceType == Matrix:DeviceType::DeviceType, );*/
-
-   this->setLike( matrix );
-   if( ! this->setCompressedRowsLengths( rowLengths ) )
-      return false;
-   Containers::Vector< RealType, Devices::Host, IndexType > values;
-   Containers::Vector< IndexType, Devices::Host, IndexType > columns;
-   if( ! values.setSize( this->getColumns() ) ||
-       ! columns.setSize( this->getColumns() ) )
-      return false;
-   for( IndexType row = 0; row < this->getRows(); row++ )
-   {
-      Assert( false, );
-      // TODO: fix this
-      //matrix.getRow( row, columns.getData(), values.getData() );
-      this->setRow( row, columns.getData(), values.getData(), rowLengths.getElement( row ) );
-   }
-   return true;
-}
-
-template< typename Real,
-          typename Device,
-          typename Index >
-Matrix< Real, Device, Index >& Matrix< Real, Device, Index >::operator = ( const Matrix< RealType, DeviceType, IndexType >& m )
-{
-   this->setLike( m );
-
-   Containers::Vector< IndexType, DeviceType, IndexType > rowLengths;
-   m.getCompressedRowsLengths( rowLengths );
-   this->setCompressedRowsLengths( rowLengths );
-
-   Containers::Vector< RealType, DeviceType, IndexType > rowValues;
-   Containers::Vector< IndexType, DeviceType, IndexType > rowColumns;
-   const IndexType maxRowLength = rowLengths.max();
-   rowValues.setSize( maxRowLength );
-   rowColumns.setSize( maxRowLength );
-   for( IndexType row = 0; row < this->getRows(); row++ )
-   {
-      m.getRow( row,
-                rowColumns.getData(),
-                rowValues.getData() );
-      this->setRow( row,
-                    rowColumns.getData(),
-                    rowValues.getData(),
-                    m.getRowLength( row ) );
-   }
-   return *this;
-}
-
 template< typename Real,
           typename Device,
           typename Index >
@@ -173,19 +115,11 @@ template< typename Real,
           typename Index >
 bool Matrix< Real, Device, Index >::save( File& file ) const
 {
-#ifdef HAVE_NOT_CXX11
-   if( ! Object::save( file ) ||
-       ! file.write< IndexType, Devices::Host, Index >( &this->rows, 1 ) ||
-       ! file.write< IndexType, Devices::Host, Index >( &this->columns, 1 ) ||
-       ! this->values.save( file ) )
-      return false;
-#else
    if( ! Object::save( file ) ||
        ! file.write( &this->rows ) ||
        ! file.write( &this->columns ) ||
        ! this->values.save( file ) )
       return false;
-#endif
    return true;
 }
 
@@ -194,19 +128,11 @@ template< typename Real,
           typename Index >
 bool Matrix< Real, Device, Index >::load( File& file )
 {
-#ifdef HAVE_NOT_CXX11
-   if( ! Object::load( file ) ||
-       ! file.read< IndexType, Devices::Host, Index >( &this->rows, 1 ) ||
-       ! file.read< IndexType, Devices::Host, Index >( &this->columns, 1 ) ||
-       ! this->values.load( file ) )
-      return false;
-#else
    if( ! Object::load( file ) ||
        ! file.read( &this->rows ) ||
        ! file.read( &this->columns ) ||
        ! this->values.load( file ) )
       return false;
-#endif
    return true;
 }
 
@@ -257,12 +183,12 @@ void MatrixVectorProductCuda( const Matrix& matrix,
                                        kernel_inVector,
                                        kernel_outVector,
                                        gridIdx );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
    }
    Devices::Cuda::freeFromDevice( kernel_this );
    Devices::Cuda::freeFromDevice( kernel_inVector );
    Devices::Cuda::freeFromDevice( kernel_outVector );
-   checkCudaDevice;
+   TNL_CHECK_CUDA_DEVICE;
 #endif
 }
 
diff --git a/src/TNL/Matrices/Multidiagonal.h b/src/TNL/Matrices/Multidiagonal.h
index 407178fe29c4840e5694e1ff4db3adf73c9ab482..28de74b8ac64b9fdf002aa71a4ca6a34a6ad4b26 100644
--- a/src/TNL/Matrices/Multidiagonal.h
+++ b/src/TNL/Matrices/Multidiagonal.h
@@ -23,12 +23,20 @@ class MultidiagonalDeviceDependentCode;
 template< typename Real, typename Device = Devices::Host, typename Index = int >
 class Multidiagonal : public Matrix< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class Multidiagonal;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Matrix< Real, Device, Index >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Matrix< Real, Device, Index >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef Multidiagonal< Real, Device, Index > ThisType;
    typedef Multidiagonal< Real, Devices::Host, Index > HostType;
    typedef Multidiagonal< Real, Devices::Cuda, Index > CudaType;
@@ -42,22 +50,29 @@ class Multidiagonal : public Matrix< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    IndexType getMaxRowLength() const;
 
    template< typename Vector >
-   bool setDiagonals( const Vector& diagonals );
+   void setDiagonals( const Vector& diagonals );
 
    const Containers::Vector< Index, Device, Index >& getDiagonals() const;
 
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Multidiagonal< Real2, Device2, Index2 >& matrix );
+   void setLike( const Multidiagonal< Real2, Device2, Index2 >& matrix );
 
    IndexType getNumberOfMatrixElements() const;
 
@@ -168,6 +183,14 @@ class Multidiagonal : public Matrix< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   Multidiagonal& operator=( const Multidiagonal& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   Multidiagonal& operator=( const Multidiagonal< Real2, Device2, Index2 >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -178,7 +201,7 @@ class Multidiagonal : public Matrix< Real, Device, Index >
 
    void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
    bool getElementIndex( const IndexType row,
                          const IndexType column,
@@ -195,8 +218,6 @@ class Multidiagonal : public Matrix< Real, Device, Index >
 
    typedef MultidiagonalDeviceDependentCode< DeviceType > DeviceDependentCode;
    friend class MultidiagonalDeviceDependentCode< DeviceType >;
-
-
 };
 
 } // namespace Matrices
diff --git a/src/TNL/Matrices/MultidiagonalMatrixSetter.h b/src/TNL/Matrices/MultidiagonalMatrixSetter.h
index f49e92fa57f052e37b5b60a2cfe56641aa477ef2..d25a21581802f63b1b16b83ed91649014a3b16df 100644
--- a/src/TNL/Matrices/MultidiagonalMatrixSetter.h
+++ b/src/TNL/Matrices/MultidiagonalMatrixSetter.h
@@ -31,7 +31,7 @@ class MultidiagonalMatrixSetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >
       typedef MeshIndex MeshIndexType;
       typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
 
       template< typename Real, typename Index >
       static bool setupMatrix( const MeshType& mesh,
@@ -52,7 +52,7 @@ class MultidiagonalMatrixSetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >
       typedef MeshIndex MeshIndexType;
       typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
 
       template< typename Real, typename Index >
       static bool setupMatrix( const MeshType& mesh,
@@ -72,7 +72,7 @@ class MultidiagonalMatrixSetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >
       typedef MeshIndex MeshIndexType;
       typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
 
       template< typename Real, typename Index >
       static bool setupMatrix( const MeshType& mesh,
diff --git a/src/TNL/Matrices/MultidiagonalMatrixSetter_impl.h b/src/TNL/Matrices/MultidiagonalMatrixSetter_impl.h
index c126162caf8d128aa473cc1896ab75059a6d130d..26f6b2994f1f46440f170e42d32689e46807ab77 100644
--- a/src/TNL/Matrices/MultidiagonalMatrixSetter_impl.h
+++ b/src/TNL/Matrices/MultidiagonalMatrixSetter_impl.h
@@ -29,14 +29,14 @@ setupMatrix( const MeshType& mesh,
    matrix.setDimensions( dofs, dofs );
    CoordinatesType centerCell( stencilSize );
    Containers::Vector< Index, Device, Index > diagonals;
-   if( ! diagonals.setSize( 3 ) )
-      return false;
+   diagonals.setSize( 3 );
    Index centerCellIndex = mesh.getCellIndex( CoordinatesType( stencilSize ) );
    diagonals.setElement( 0, mesh.getCellIndex( CoordinatesType( stencilSize - 1 ) ) - centerCellIndex );
    diagonals.setElement( 1, 0 );
    diagonals.setElement( 2, mesh.getCellIndex( CoordinatesType( stencilSize + 1 ) ) - centerCellIndex );
    //cout << "Setting the multidiagonal matrix offsets to: " << diagonals << std::endl;
-   return matrix.setDiagonals( diagonals );
+   matrix.setDiagonals( diagonals );
+   return true;
 }
 
 template< typename MeshReal,
@@ -55,8 +55,7 @@ setupMatrix( const MeshType& mesh,
    matrix.setDimensions( dofs, dofs );
    CoordinatesType centerCell( stencilSize );
    Containers::Vector< Index, Device, Index > diagonals;
-   if( ! diagonals.setSize( 5 ) )
-      return false;
+   diagonals.setSize( 5 );
    Index centerCellIndex = mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize ) );
    diagonals.setElement( 0, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize - 1 ) ) - centerCellIndex );
    diagonals.setElement( 1, mesh.getCellIndex( CoordinatesType( stencilSize - 1, stencilSize ) ) - centerCellIndex );
@@ -64,7 +63,8 @@ setupMatrix( const MeshType& mesh,
    diagonals.setElement( 3, mesh.getCellIndex( CoordinatesType( stencilSize + 1, stencilSize ) ) - centerCellIndex );
    diagonals.setElement( 4, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize + 1 ) ) - centerCellIndex );
    //cout << "Setting the multidiagonal matrix offsets to: " << diagonals << std::endl;
-   return matrix.setDiagonals( diagonals );
+   matrix.setDiagonals( diagonals );
+   return true;
 }
 
 template< typename MeshReal,
@@ -83,8 +83,7 @@ setupMatrix( const MeshType& mesh,
    matrix.setDimensions( dofs, dofs );
    CoordinatesType centerCell( stencilSize );
    Containers::Vector< Index, Device, Index > diagonals;
-   if( ! diagonals.setSize( 7 ) )
-      return false;
+   diagonals.setSize( 7 );
    Index centerCellIndex = mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize, stencilSize ) );
    diagonals.setElement( 0, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize, stencilSize - 1 ) ) - centerCellIndex );
    diagonals.setElement( 1, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize - 1, stencilSize ) ) - centerCellIndex );
@@ -94,7 +93,8 @@ setupMatrix( const MeshType& mesh,
    diagonals.setElement( 5, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize + 1, stencilSize ) ) - centerCellIndex );
    diagonals.setElement( 6, mesh.getCellIndex( CoordinatesType( stencilSize, stencilSize, stencilSize + 1 ) ) - centerCellIndex );
    //cout << "Setting the multidiagonal matrix offsets to: " << diagonals << std::endl;
-   return matrix.setDiagonals( diagonals );
+   matrix.setDiagonals( diagonals );
+   return true;
 }
 
 } // namespace Matrices
diff --git a/src/TNL/Matrices/MultidiagonalRow_impl.h b/src/TNL/Matrices/MultidiagonalRow_impl.h
index 6fe47d4decf68929e2c2abd48d7c1ba23ab32d56..2765188c1a18fc028e27b455ca3a9986c23409f1 100644
--- a/src/TNL/Matrices/MultidiagonalRow_impl.h
+++ b/src/TNL/Matrices/MultidiagonalRow_impl.h
@@ -71,16 +71,16 @@ setElement( const Index& elementIndex,
             const Index& column,
             const Real& value )
 {
-   Assert( this->values, );
-   Assert( this->step > 0,);
-   Assert( column >= 0 && column < this->columns,
+   TNL_ASSERT( this->values, );
+   TNL_ASSERT( this->step > 0,);
+   TNL_ASSERT( column >= 0 && column < this->columns,
               std::cerr << "column = " << columns << " this->columns = " << this->columns );
-   Assert( elementIndex >= 0 && elementIndex < this->maxRowLength,
+   TNL_ASSERT( elementIndex >= 0 && elementIndex < this->maxRowLength,
               std::cerr << "elementIndex = " << elementIndex << " this->maxRowLength =  " << this->maxRowLength );
 
    Index aux = elementIndex;
    while( row + this->diagonals[ aux ] < column ) aux++;
-   Assert( row + this->diagonals[ aux ] == column,
+   TNL_ASSERT( row + this->diagonals[ aux ] == column,
               std::cerr << "row = " << row
                    << " aux = " << aux
                    << " this->diagonals[ aux ] = " << this->diagonals[ aux]
diff --git a/src/TNL/Matrices/Multidiagonal_impl.h b/src/TNL/Matrices/Multidiagonal_impl.h
index 1e3463657ee9084699622fc5ce511a04f0d8441d..47d827b93df0904b568c234cc8bfbea602479e46 100644
--- a/src/TNL/Matrices/Multidiagonal_impl.h
+++ b/src/TNL/Matrices/Multidiagonal_impl.h
@@ -50,32 +50,44 @@ String Multidiagonal< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                                   const IndexType columns )
+String Multidiagonal< Real, Device, Index >::getSerializationType()
 {
-   Assert( rows > 0 && columns > 0,
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String Multidiagonal< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void Multidiagonal< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                          const IndexType columns )
+{
+   TNL_ASSERT( rows > 0 && columns > 0,
               std::cerr << "rows = " << rows
                    << " columns = " << columns << std::endl );
-   if( ! Matrix< Real, Device, Index >::setDimensions( rows, columns ) )
-      return false;
+   Matrix< Real, Device, Index >::setDimensions( rows, columns );
    if( this->diagonalsShift.getSize() != 0 )
    {
-      if( ! this->values.setSize( min( this->rows, this->columns ) * this->diagonalsShift.getSize() ) )
-         return false;
+      this->values.setSize( min( this->rows, this->columns ) * this->diagonalsShift.getSize() );
       this->values.setValue( 0.0 );
    }
-   return true;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void Multidiagonal< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
    /****
     * TODO: implement some check here similar to the one in the tridiagonal matrix
     */
-   return true;
 }
 
 template< typename Real,
@@ -93,6 +105,22 @@ Index Multidiagonal< Real, Device, Index >::getRowLength( const IndexType row )
    return rowLength;
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index Multidiagonal< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
+{
+   IndexType rowLength( 0 );
+   for( IndexType i = 0; i < diagonalsShift.getSize(); i++ )
+   {
+      const IndexType column = row + diagonalsShift[ i ];
+      if( column >= 0 && column < this->getColumns() )
+         rowLength++;
+   }
+   return rowLength;
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -107,19 +135,17 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename Vector >
-bool Multidiagonal< Real, Device, Index > :: setDiagonals(  const Vector& diagonals )
+void Multidiagonal< Real, Device, Index > :: setDiagonals(  const Vector& diagonals )
 {
-   Assert( diagonals.getSize() > 0,
+   TNL_ASSERT( diagonals.getSize() > 0,
               std::cerr << "New number of diagonals = " << diagonals.getSize() << std::endl );
    this->diagonalsShift.setLike( diagonals );
    this->diagonalsShift = diagonals;
    if( this->rows != 0 && this->columns != 0 )
    {
-      if( ! this->values.setSize( min( this->rows, this->columns ) * this->diagonalsShift.getSize() ) )
-         return false;
+      this->values.setSize( min( this->rows, this->columns ) * this->diagonalsShift.getSize() );
       this->values.setValue( 0.0 );
    }
-   return true;
 }
 
 template< typename Real,
@@ -136,13 +162,10 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool Multidiagonal< Real, Device, Index > :: setLike( const Multidiagonal< Real2, Device2, Index2 >& matrix )
+void Multidiagonal< Real, Device, Index > :: setLike( const Multidiagonal< Real2, Device2, Index2 >& matrix )
 {
-   if( ! this->setDimensions( matrix.getRows(), matrix.getColumns() ) )
-      return false;
-   if( ! setDiagonals( matrix.getDiagonals() ) )
-      return false;
-   return true;
+   this->setDimensions( matrix.getRows(), matrix.getColumns() );
+   setDiagonals( matrix.getDiagonals() );
 }
 
 template< typename Real,
@@ -183,7 +206,7 @@ template< typename Real,
              typename Index2 >
 bool Multidiagonal< Real, Device, Index >::operator == ( const Multidiagonal< Real2, Device2, Index2 >& matrix ) const
 {
-   Assert( this->getRows() == matrix.getRows() &&
+   TNL_ASSERT( this->getRows() == matrix.getRows() &&
               this->getColumns() == matrix.getColumns(),
               std::cerr << "this->getRows() = " << this->getRows()
                    << " matrix.getRows() = " << matrix.getRows()
@@ -503,10 +526,10 @@ template< typename Real,
 void Multidiagonal< Real, Device, Index >::vectorProduct( const InVector& inVector,
                                                                    OutVector& outVector ) const
 {
-   Assert( this->getColumns() == inVector.getSize(),
+   TNL_ASSERT( this->getColumns() == inVector.getSize(),
             std::cerr << "Matrix columns: " << this->getColumns() << std::endl
                  << "Vector size: " << inVector.getSize() << std::endl );
-   Assert( this->getRows() == outVector.getSize(),
+   TNL_ASSERT( this->getRows() == outVector.getSize(),
                std::cerr << "Matrix rows: " << this->getRows() << std::endl
                     << "Vector size: " << outVector.getSize() << std::endl );
 
@@ -522,7 +545,7 @@ void Multidiagonal< Real, Device, Index > :: addMatrix( const Multidiagonal< Rea
                                                                  const RealType& matrixMultiplicator,
                                                                  const RealType& thisMatrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
 }
 
 template< typename Real,
@@ -559,7 +582,7 @@ bool Multidiagonal< Real, Device, Index > :: performSORIteration( const Vector&
                                                                            Vector& x,
                                                                            const RealType& omega ) const
 {
-   Assert( row >=0 && row < this->getRows(),
+   TNL_ASSERT( row >=0 && row < this->getRows(),
               std::cerr << "row = " << row
                    << " this->getRows() = " << this->getRows() << std::endl );
 
@@ -591,6 +614,39 @@ bool Multidiagonal< Real, Device, Index > :: performSORIteration( const Vector&
 }
 
 
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+Multidiagonal< Real, Device, Index >&
+Multidiagonal< Real, Device, Index >::operator=( const Multidiagonal& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->diagonalsShift = matrix.diagonalsShift;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+Multidiagonal< Real, Device, Index >&
+Multidiagonal< Real, Device, Index >::operator=( const Multidiagonal< Real2, Device2, Index2 >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value,
+                  "unknown device" );
+
+   this->setLike( matrix );
+
+   std::cerr << "Cross-device assignment for the Multidiagonal format is not implemented yet." << std::endl;
+   throw 1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -654,10 +710,10 @@ bool Multidiagonal< Real, Device, Index >::getElementIndex( const IndexType row,
                                                                      const IndexType column,
                                                                      Index& index ) const
 {
-   Assert( row >=0 && row < this->rows,
+   TNL_ASSERT( row >=0 && row < this->rows,
             std::cerr << "row = " << row
                  << " this->rows = " << this->rows << std::endl );
-   Assert( column >=0 && column < this->columns,
+   TNL_ASSERT( column >=0 && column < this->columns,
             std::cerr << "column = " << column
                  << " this->columns = " << this->columns << std::endl );
 
@@ -683,10 +739,10 @@ bool Multidiagonal< Real, Device, Index >::getElementIndexFast( const IndexType
                                                                          const IndexType column,
                                                                          Index& index ) const
 {
-   Assert( row >=0 && row < this->rows,
+   TNL_ASSERT( row >=0 && row < this->rows,
             std::cerr << "row = " << row
                  << " this->rows = " << this->rows << std::endl );
-   Assert( column >=0 && column < this->columns,
+   TNL_ASSERT( column >=0 && column < this->columns,
             std::cerr << "column = " << column
                  << " this->columns = " << this->columns << std::endl );
 
diff --git a/src/TNL/Matrices/SlicedEllpack.h b/src/TNL/Matrices/SlicedEllpack.h
index a496f544ebad6d77f8420425a821e777c9f25612..0557d26ebbd94ee57ab2bcd51bb029f48cbd30c7 100644
--- a/src/TNL/Matrices/SlicedEllpack.h
+++ b/src/TNL/Matrices/SlicedEllpack.h
@@ -41,7 +41,7 @@ template< typename Real,
           typename Index,
           int SliceSize >
 __global__ void SlicedEllpack_computeMaximalRowLengthInSlices_CudaKernel( SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >* matrix,
-                                                                                   const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowsLengthsVector* rowLengths,
+                                                                                   const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowLengthsVector* rowLengths,
                                                                                    int gridIdx );
 #endif
 
@@ -51,19 +51,28 @@ template< typename Real,
           int SliceSize >
 class SlicedEllpack : public Sparse< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2, int SliceSize2 >
+   friend class SlicedEllpack;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Sparse< RealType, DeviceType, IndexType >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Sparse< RealType, DeviceType, IndexType >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef typename Sparse< RealType, DeviceType, IndexType >::ValuesVector ValuesVector;
    typedef typename Sparse< RealType, DeviceType, IndexType >::ColumnIndexesVector ColumnIndexesVector;
-   typedef SlicedEllpack< Real, Device, Index > ThisType;
-   typedef SlicedEllpack< Real, Devices::Host, Index > HostType;
-   typedef SlicedEllpack< Real, Devices::Cuda, Index > CudaType;
+   typedef SlicedEllpack< Real, Device, Index, SliceSize > ThisType;
+   typedef SlicedEllpack< Real, Devices::Host, Index, SliceSize > HostType;
+   typedef SlicedEllpack< Real, Devices::Cuda, Index, SliceSize > CudaType;
    typedef Sparse< Real, Device, Index > BaseType;
    typedef typename BaseType::MatrixRow MatrixRow;
+   typedef SparseRow< const RealType, const IndexType > ConstMatrixRow;
 
 
    SlicedEllpack();
@@ -72,15 +81,22 @@ class SlicedEllpack : public Sparse< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix );
+   void setLike( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix );
 
    void reset();
 
@@ -150,7 +166,7 @@ class SlicedEllpack : public Sparse< Real, Device, Index >
    MatrixRow getRow( const IndexType rowIndex );
 
    __cuda_callable__
-   const MatrixRow getRow( const IndexType rowIndex ) const;
+   ConstMatrixRow getRow( const IndexType rowIndex ) const;
 
    template< typename Vector >
    __cuda_callable__
@@ -177,6 +193,14 @@ class SlicedEllpack : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   SlicedEllpack& operator=( const SlicedEllpack& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   SlicedEllpack& operator=( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -187,25 +211,23 @@ class SlicedEllpack : public Sparse< Real, Device, Index >
 
    void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
-   Containers::Vector< Index, Device, Index > slicePointers, sliceCompressedRowsLengths;
+   Containers::Vector< Index, Device, Index > slicePointers, sliceCompressedRowLengths;
 
    typedef SlicedEllpackDeviceDependentCode< DeviceType > DeviceDependentCode;
    friend class SlicedEllpackDeviceDependentCode< DeviceType >;
 #ifdef HAVE_CUDA
    /*friend __global__ void SlicedEllpack_computeMaximalRowLengthInSlices_CudaKernel< Real, Index, SliceSize >( SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >* matrix,
-                                                                                      const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowsLengthsVector* rowLengths,
+                                                                                      const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowLengthsVector* rowLengths,
                                                                                       int gridIdx );
     */
    // TODO: The friend declaration above does not work because of __global__ storage specifier. Therefore we declare the following method as public. Fix this, when possible.
 
-   public:
-   __device__ void computeMaximalRowLengthInSlicesCuda( const CompressedRowsLengthsVector& rowLengths,
+public:
+   __device__ void computeMaximalRowLengthInSlicesCuda( const CompressedRowLengthsVector& rowLengths,
                                                         const IndexType sliceIdx );
-
 #endif
-
 };
 
 } // namespace Matrices
diff --git a/src/TNL/Matrices/SlicedEllpack_impl.h b/src/TNL/Matrices/SlicedEllpack_impl.h
index d15c38c12118240c42fd9f3aa0a743c78cbe9197..a08aaf19bc479ce4f9fa7c4b99775af0479c78b0 100644
--- a/src/TNL/Matrices/SlicedEllpack_impl.h
+++ b/src/TNL/Matrices/SlicedEllpack_impl.h
@@ -51,34 +51,53 @@ template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::setDimensions( const IndexType rows,
-                                                                              const IndexType columns )
+String SlicedEllpack< Real, Device, Index, SliceSize >::getSerializationType()
 {
-   Assert( rows > 0 && columns > 0,
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          int SliceSize >
+String SlicedEllpack< Real, Device, Index, SliceSize >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          int SliceSize >
+void SlicedEllpack< Real, Device, Index, SliceSize >::setDimensions( const IndexType rows,
+                                                                     const IndexType columns )
+{
+   TNL_ASSERT( rows > 0 && columns > 0,
               std::cerr << "rows = " << rows
                    << " columns = " << columns << std::endl );
-   return Sparse< Real, Device, Index >::setDimensions( rows, columns );
+   Sparse< Real, Device, Index >::setDimensions( rows, columns );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void SlicedEllpack< Real, Device, Index, SliceSize >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
-   Assert( this->getRows() > 0, );
-   Assert( this->getColumns() > 0, );
+   TNL_ASSERT_GT( this->getRows(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_GT( this->getColumns(), 0, "cannot set row lengths of an empty matrix" );
+   TNL_ASSERT_EQ( this->getRows(), rowLengths.getSize(), "wrong size of the rowLengths vector" );
+
    const IndexType slices = roundUpDivision( this->rows, SliceSize );
-   if( ! this->sliceCompressedRowsLengths.setSize( slices ) ||
-       ! this->slicePointers.setSize( slices + 1 ) )
-      return false;
+   this->sliceCompressedRowLengths.setSize( slices );
+   this->slicePointers.setSize( slices + 1 );
 
    DeviceDependentCode::computeMaximalRowLengthInSlices( *this, rowLengths );
 
    this->maxRowLength = rowLengths.max();
 
    this->slicePointers.computeExclusivePrefixSum();
-   return this->allocateMatrixElements( this->slicePointers.getElement( slices ) );
+   this->allocateMatrixElements( this->slicePointers.getElement( slices ) );
 }
 
 template< typename Real,
@@ -88,7 +107,18 @@ template< typename Real,
 Index SlicedEllpack< Real, Device, Index, SliceSize >::getRowLength( const IndexType row ) const
 {
    const IndexType slice = row / SliceSize;
-   return this->sliceCompressedRowsLengths.getElement( slice );
+   return this->sliceCompressedRowLengths.getElement( slice );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          int SliceSize >
+__cuda_callable__
+Index SlicedEllpack< Real, Device, Index, SliceSize >::getRowLengthFast( const IndexType row ) const
+{
+   const IndexType slice = row / SliceSize;
+   return this->sliceCompressedRowLengths[ slice ];
 }
 
 template< typename Real,
@@ -98,13 +128,11 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::setLike( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix )
+void SlicedEllpack< Real, Device, Index, SliceSize >::setLike( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix )
 {
-   if( !Sparse< Real, Device, Index >::setLike( matrix ) ||
-       ! this->slicePointers.setLike( matrix.slicePointers ) ||
-       ! this->sliceCompressedRowsLengths.setLike( matrix.sliceCompressedRowsLengths ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::setLike( matrix );
+   this->slicePointers.setLike( matrix.slicePointers );
+   this->sliceCompressedRowLengths.setLike( matrix.sliceCompressedRowLengths );
 }
 
 template< typename Real,
@@ -115,7 +143,7 @@ void SlicedEllpack< Real, Device, Index, SliceSize >::reset()
 {
    Sparse< Real, Device, Index >::reset();
    this->slicePointers.reset();
-   this->sliceCompressedRowsLengths.reset();
+   this->sliceCompressedRowLengths.reset();
 }
 
 template< typename Real,
@@ -127,7 +155,7 @@ template< typename Real,
              typename Index2 >
 bool SlicedEllpack< Real, Device, Index, SliceSize >::operator == ( const SlicedEllpack< Real2, Device2, Index2 >& matrix ) const
 {
-   Assert( this->getRows() == matrix.getRows() &&
+   TNL_ASSERT( this->getRows() == matrix.getRows() &&
               this->getColumns() == matrix.getColumns(),
               std::cerr << "this->getRows() = " << this->getRows()
                    << " matrix.getRows() = " << matrix.getRows()
@@ -183,7 +211,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::addElementFast( const Inde
                                                                                const RealType& value,
                                                                                const RealType& thisElementMultiplicator )
 {
-   Assert( row >= 0 && row < this->rows &&
+   TNL_ASSERT( row >= 0 && row < this->rows &&
               column >= 0 && column <= this->rows,
               std::cerr << " row = " << row
                    << " column = " << column
@@ -231,7 +259,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::addElement( const IndexTyp
                                                                            const RealType& value,
                                                                            const RealType& thisElementMultiplicator )
 {
-   Assert( row >= 0 && row < this->rows &&
+   TNL_ASSERT( row >= 0 && row < this->rows &&
               column >= 0 && column <= this->rows,
               std::cerr << " row = " << row
                    << " column = " << column
@@ -281,7 +309,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize > :: setRowFast( const IndexT
                                                                              const IndexType elements )
 {
    const IndexType sliceIdx = row / SliceSize;
-   const IndexType rowLength = this->sliceCompressedRowsLengths[ sliceIdx ];
+   const IndexType rowLength = this->sliceCompressedRowLengths[ sliceIdx ];
    if( elements > rowLength )
       return false;
 
@@ -315,7 +343,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize > :: setRow( const IndexType
                                                                          const IndexType elements )
 {
    const IndexType sliceIdx = row / SliceSize;
-   const IndexType rowLength = this->sliceCompressedRowsLengths.getElement( sliceIdx );
+   const IndexType rowLength = this->sliceCompressedRowLengths.getElement( sliceIdx );
    if( elements > rowLength )
       return false;
 
@@ -445,7 +473,7 @@ getRow( const IndexType rowIndex )
    const IndexType slice = rowIndex / SliceSize;
    return MatrixRow( &this->columnIndexes[ rowBegin ],
                      &this->values[ rowBegin ],
-                     this->sliceCompressedRowsLengths[ slice ],
+                     this->sliceCompressedRowLengths[ slice ],
                      step );
 }
 
@@ -454,17 +482,17 @@ template< typename Real,
           typename Index,
           int SliceSize >
 __cuda_callable__
-const typename SlicedEllpack< Real, Device, Index, SliceSize >::MatrixRow
+typename SlicedEllpack< Real, Device, Index, SliceSize >::ConstMatrixRow
 SlicedEllpack< Real, Device, Index, SliceSize >::
 getRow( const IndexType rowIndex ) const
 {
    Index rowBegin, rowEnd, step;
    DeviceDependentCode::initRowTraverseFast( *this, rowIndex, rowBegin, rowEnd, step );
    const IndexType slice = rowIndex / SliceSize;
-   return MatrixRow( &this->columnIndexes[ rowBegin ],
-                     &this->values[ rowBegin ],
-                     this->sliceCompressedRowsLengths[ slice ],
-                     step );
+   return ConstMatrixRow( &this->columnIndexes[ rowBegin ],
+                          &this->values[ rowBegin ],
+                          this->sliceCompressedRowLengths[ slice ],
+                          step );
 }
 
 template< typename Real,
@@ -513,7 +541,7 @@ void SlicedEllpack< Real, Device, Index, SliceSize >::addMatrix( const SlicedEll
                                                                           const RealType& matrixMultiplicator,
                                                                           const RealType& thisMatrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -526,7 +554,7 @@ template< typename Real,
 void SlicedEllpack< Real, Device, Index, SliceSize >::getTransposition( const SlicedEllpack< Real2, Device, Index2 >& matrix,
                                                                       const RealType& matrixMultiplicator )
 {
-   Assert( false, std::cerr << "TODO: implement" );
+   TNL_ASSERT( false, std::cerr << "TODO: implement" );
    // TODO: implement
 }
 
@@ -540,7 +568,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::performSORIteration( const
                                                                                     Vector& x,
                                                                                     const RealType& omega ) const
 {
-   Assert( row >=0 && row < this->getRows(),
+   TNL_ASSERT( row >=0 && row < this->getRows(),
               std::cerr << "row = " << row
                    << " this->getRows() = " << this->getRows() << std::endl );
 
@@ -548,7 +576,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::performSORIteration( const
    RealType sum( 0.0 );
 
    /*const IndexType sliceIdx = row / SliceSize;
-   const IndexType rowLength = this->sliceCompressedRowsLengths[ sliceIdx ];
+   const IndexType rowLength = this->sliceCompressedRowLengths[ sliceIdx ];
    IndexType elementPtr = this->slicePointers[ sliceIdx ] +
                           rowLength * ( row - sliceIdx * SliceSize );
    const IndexType rowEnd( elementPtr + rowLength );*/
@@ -573,6 +601,95 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::performSORIteration( const
 }
 
 
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index,
+          int SliceSize >
+SlicedEllpack< Real, Device, Index, SliceSize >&
+SlicedEllpack< Real, Device, Index, SliceSize >::operator=( const SlicedEllpack& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   this->columnIndexes = matrix.columnIndexes;
+   this->slicePointers = matrix.slicePointers;
+   this->sliceCompressedRowLengths = matrix.sliceCompressedRowLengths;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index,
+          int SliceSize >
+   template< typename Real2, typename Device2, typename Index2, typename >
+SlicedEllpack< Real, Device, Index, SliceSize >&
+SlicedEllpack< Real, Device, Index, SliceSize >::operator=( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value || std::is_same< Device, Devices::MIC >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value || std::is_same< Device2, Devices::MIC >::value,
+                  "unknown device" );
+
+   this->setLike( matrix );
+   this->slicePointers = matrix.slicePointers;
+   this->sliceCompressedRowLengths = matrix.sliceCompressedRowLengths;
+
+   // host -> cuda
+   if( std::is_same< Device, Devices::Cuda >::value ) {
+      typename ValuesVector::HostType tmpValues;
+      typename ColumnIndexesVector::HostType tmpColumnIndexes;
+      tmpValues.setLike( matrix.values );
+      tmpColumnIndexes.setLike( matrix.columnIndexes );
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( Index sliceIdx = 0; sliceIdx < matrix.sliceCompressedRowLengths.getSize(); sliceIdx++ ) {
+         const Index rowLength = matrix.sliceCompressedRowLengths[ sliceIdx ];
+         const Index offset = matrix.slicePointers[ sliceIdx ];
+         for( Index j = 0; j < rowLength; j++ )
+            for( Index i = 0; i < SliceSize; i++ ) {
+               tmpValues[ offset + j * SliceSize + i ] = matrix.values[ offset + i * rowLength + j ];
+               tmpColumnIndexes[ offset + j * SliceSize + i ] = matrix.columnIndexes[ offset + i * rowLength + j ];
+            }
+      }
+
+      this->values = tmpValues;
+      this->columnIndexes = tmpColumnIndexes;
+   }
+
+   // cuda -> host
+   if( std::is_same< Device, Devices::Host >::value ) {
+      ValuesVector tmpValues;
+      ColumnIndexesVector tmpColumnIndexes;
+      tmpValues.setLike( matrix.values );
+      tmpColumnIndexes.setLike( matrix.columnIndexes );
+      tmpValues = matrix.values;
+      tmpColumnIndexes = matrix.columnIndexes;
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( Index sliceIdx = 0; sliceIdx < sliceCompressedRowLengths.getSize(); sliceIdx++ ) {
+         const Index rowLength = sliceCompressedRowLengths[ sliceIdx ];
+         const Index offset = slicePointers[ sliceIdx ];
+         for( Index i = 0; i < SliceSize; i++ )
+            for( Index j = 0; j < rowLength; j++ ) {
+               this->values[ offset + i * rowLength + j ] = tmpValues[ offset + j * SliceSize + i ];
+               this->columnIndexes[ offset + i * rowLength + j ] = tmpColumnIndexes[ offset + j * SliceSize + i ];
+            }
+      }
+   }
+   
+   if( std::is_same< Device, Devices::MIC >::value ) {
+      throw std::runtime_error("Not Implemented yet for MIC");
+   }
+
+   return *this;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index,
@@ -581,7 +698,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::save( File& file ) const
 {
    if( ! Sparse< Real, Device, Index >::save( file ) ||
        ! this->slicePointers.save( file ) ||
-       ! this->sliceCompressedRowsLengths.save( file ) )
+       ! this->sliceCompressedRowLengths.save( file ) )
       return false;
    return true;
 }
@@ -594,7 +711,7 @@ bool SlicedEllpack< Real, Device, Index, SliceSize >::load( File& file )
 {
    if( ! Sparse< Real, Device, Index >::load( file ) ||
        ! this->slicePointers.load( file ) ||
-       ! this->sliceCompressedRowsLengths.load( file ) )
+       ! this->sliceCompressedRowLengths.load( file ) )
       return false;
    return true;
 }
@@ -623,23 +740,30 @@ template< typename Real,
           int SliceSize >
 void SlicedEllpack< Real, Device, Index, SliceSize >::print( std::ostream& str ) const
 {
-   for( IndexType row = 0; row < this->getRows(); row++ )
-   {
-      str <<"Row: " << row << " -> ";
-      const IndexType sliceIdx = row / SliceSize;
-      const IndexType rowLength = this->sliceCompressedRowsLengths.getElement( sliceIdx );
-      IndexType elementPtr = this->slicePointers.getElement( sliceIdx ) +
-                             rowLength * ( row - sliceIdx * SliceSize );
-      const IndexType rowEnd( elementPtr + rowLength );
-      while( elementPtr < rowEnd &&
-             this->columnIndexes.getElement( elementPtr ) < this->columns &&
-             this->columnIndexes.getElement( elementPtr ) != this->getPaddingIndex() )
+   if( std::is_same< Device, Devices::Host >::value ) {
+      for( IndexType row = 0; row < this->getRows(); row++ )
       {
-         const Index column = this->columnIndexes.getElement( elementPtr );
-         str << " Col:" << column << "->" << this->values.getElement( elementPtr ) << "\t";
-         elementPtr++;
+         str <<"Row: " << row << " -> ";
+         const IndexType sliceIdx = row / SliceSize;
+         const IndexType rowLength = this->sliceCompressedRowLengths.getElement( sliceIdx );
+         IndexType elementPtr = this->slicePointers.getElement( sliceIdx ) +
+                                rowLength * ( row - sliceIdx * SliceSize );
+         const IndexType rowEnd( elementPtr + rowLength );
+         while( elementPtr < rowEnd &&
+                this->columnIndexes.getElement( elementPtr ) < this->columns &&
+                this->columnIndexes.getElement( elementPtr ) != this->getPaddingIndex() )
+         {
+            const Index column = this->columnIndexes.getElement( elementPtr );
+            str << " Col:" << column << "->" << this->values.getElement( elementPtr ) << "\t";
+            elementPtr++;
+         }
+         str << std::endl;
       }
-      str << std::endl;
+   }
+   else {
+      HostType hostMatrix;
+      hostMatrix = *this;
+      hostMatrix.print( str );
    }
 }
 
@@ -648,7 +772,7 @@ template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-__device__ void SlicedEllpack< Real, Device, Index, SliceSize >::computeMaximalRowLengthInSlicesCuda( const CompressedRowsLengthsVector& rowLengths,
+__device__ void SlicedEllpack< Real, Device, Index, SliceSize >::computeMaximalRowLengthInSlicesCuda( const CompressedRowLengthsVector& rowLengths,
                                                                                                                const IndexType sliceIdx )
 {
    Index rowIdx = sliceIdx * SliceSize;
@@ -662,7 +786,7 @@ __device__ void SlicedEllpack< Real, Device, Index, SliceSize >::computeMaximalR
       rowIdx++;
       rowInSliceIdx++;
    }
-   this->sliceCompressedRowsLengths[ sliceIdx ] = maxRowLength;
+   this->sliceCompressedRowLengths[ sliceIdx ] = maxRowLength;
    this->slicePointers[ sliceIdx ] = maxRowLength * SliceSize;
    if( threadIdx.x == 0 )
       this->slicePointers[ this->slicePointers.getSize() - 1 ] = 0;
@@ -688,7 +812,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Host >
       {
          const Index sliceIdx = row / SliceSize;
          const Index slicePointer = matrix.slicePointers.getElement( sliceIdx );
-         const Index rowLength = matrix.sliceCompressedRowsLengths.getElement( sliceIdx );
+         const Index rowLength = matrix.sliceCompressedRowLengths.getElement( sliceIdx );
 
          rowBegin = slicePointer + rowLength * ( row - sliceIdx * SliceSize );
          rowEnd = rowBegin + rowLength;
@@ -707,7 +831,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Host >
       {
          const Index sliceIdx = row / SliceSize;
          const Index slicePointer = matrix.slicePointers[ sliceIdx ];
-         const Index rowLength = matrix.sliceCompressedRowsLengths[ sliceIdx ];
+         const Index rowLength = matrix.sliceCompressedRowLengths[ sliceIdx ];
 
          rowBegin = slicePointer + rowLength * ( row - sliceIdx * SliceSize );
          rowEnd = rowBegin + rowLength;
@@ -719,7 +843,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Host >
                 typename Index,
                 int SliceSize >
       static bool computeMaximalRowLengthInSlices( SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
-                                                   const typename SlicedEllpack< Real, Device, Index >::CompressedRowsLengthsVector& rowLengths )
+                                                   const typename SlicedEllpack< Real, Device, Index >::CompressedRowLengthsVector& rowLengths )
       {
          Index row( 0 ), slice( 0 ), sliceRowLength( 0 );
          while( row < matrix.getRows() )
@@ -727,14 +851,14 @@ class SlicedEllpackDeviceDependentCode< Devices::Host >
             sliceRowLength = max( rowLengths.getElement( row++ ), sliceRowLength );
             if( row % SliceSize == 0 )
             {
-               matrix.sliceCompressedRowsLengths.setElement( slice, sliceRowLength );
+               matrix.sliceCompressedRowLengths.setElement( slice, sliceRowLength );
                matrix.slicePointers.setElement( slice++, sliceRowLength * SliceSize );
                sliceRowLength = 0;
             }
          }
          if( row % SliceSize != 0 )
          {
-            matrix.sliceCompressedRowsLengths.setElement( slice, sliceRowLength );
+            matrix.sliceCompressedRowLengths.setElement( slice, sliceRowLength );
             matrix.slicePointers.setElement( slice++, sliceRowLength * SliceSize );
          }
          matrix.slicePointers.setElement( matrix.slicePointers.getSize() - 1, 0 );
@@ -764,7 +888,7 @@ template< typename Real,
           typename Index,
           int SliceSize >
 __global__ void SlicedEllpack_computeMaximalRowLengthInSlices_CudaKernel( SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >* matrix,
-                                                                                   const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowsLengthsVector* rowLengths,
+                                                                                   const typename SlicedEllpack< Real, Devices::Cuda, Index, SliceSize >::CompressedRowLengthsVector* rowLengths,
                                                                                    int gridIdx )
 {
    const Index sliceIdx = gridIdx * Devices::Cuda::getMaxGridSize() * blockDim.x + blockIdx.x * blockDim.x + threadIdx.x;
@@ -781,7 +905,7 @@ __global__ void SlicedEllpackVectorProductCudaKernel(
    const Index rows,
    const Index columns,
    const Index* slicePointers,
-   const Index* sliceCompressedRowsLengths,
+   const Index* sliceCompressedRowLengths,
    const Index paddingIndex,
    const Index* columnIndexes,
    const Real* values,
@@ -794,7 +918,7 @@ __global__ void SlicedEllpackVectorProductCudaKernel(
       return;
    const Index sliceIdx = rowIdx / SliceSize;
    const Index slicePointer = slicePointers[ sliceIdx ];
-   const Index rowLength = sliceCompressedRowsLengths[ sliceIdx ];
+   const Index rowLength = sliceCompressedRowLengths[ sliceIdx ];
    Index i = slicePointer + rowIdx - sliceIdx * SliceSize;
    const Index rowEnd = i + rowLength * SliceSize;
    Real result( 0.0 );
@@ -829,7 +953,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Cuda >
       {
          const Index sliceIdx = row / SliceSize;
          const Index slicePointer = matrix.slicePointers.getElement( sliceIdx );
-         const Index rowLength = matrix.sliceCompressedRowsLengths.getElement( sliceIdx );
+         const Index rowLength = matrix.sliceCompressedRowLengths.getElement( sliceIdx );
 
          rowBegin = slicePointer + row - sliceIdx * SliceSize;
          rowEnd = rowBegin + rowLength * SliceSize;
@@ -848,7 +972,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Cuda >
       {
          const Index sliceIdx = row / SliceSize;
          const Index slicePointer = matrix.slicePointers[ sliceIdx ];
-         const Index rowLength = matrix.sliceCompressedRowsLengths[ sliceIdx ];
+         const Index rowLength = matrix.sliceCompressedRowLengths[ sliceIdx ];
 
          rowBegin = slicePointer + row - sliceIdx * SliceSize;
          rowEnd = rowBegin + rowLength * SliceSize;
@@ -860,13 +984,13 @@ class SlicedEllpackDeviceDependentCode< Devices::Cuda >
                 typename Index,
                 int SliceSize >
       static bool computeMaximalRowLengthInSlices( SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
-                                                   const typename SlicedEllpack< Real, Device, Index >::CompressedRowsLengthsVector& rowLengths )
+                                                   const typename SlicedEllpack< Real, Device, Index >::CompressedRowLengthsVector& rowLengths )
       {
 #ifdef HAVE_CUDA
          typedef SlicedEllpack< Real, Device, Index, SliceSize > Matrix;
-         typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+         typedef typename Matrix::CompressedRowLengthsVector CompressedRowLengthsVector;
          Matrix* kernel_matrix = Devices::Cuda::passToDevice( matrix );
-         CompressedRowsLengthsVector* kernel_rowLengths = Devices::Cuda::passToDevice( rowLengths );
+         CompressedRowLengthsVector* kernel_rowLengths = Devices::Cuda::passToDevice( rowLengths );
          const Index numberOfSlices = roundUpDivision( matrix.getRows(), SliceSize );
          dim3 cudaBlockSize( 256 ), cudaGridSize( Devices::Cuda::getMaxGridSize() );
          const Index cudaBlocks = roundUpDivision( numberOfSlices, cudaBlockSize.x );
@@ -882,7 +1006,7 @@ class SlicedEllpackDeviceDependentCode< Devices::Cuda >
          }
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_rowLengths );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
          return true;
       }
@@ -916,24 +1040,78 @@ class SlicedEllpackDeviceDependentCode< Devices::Cuda >
                 ( matrix.getRows(),
                   matrix.getColumns(),
                   matrix.slicePointers.getData(),
-                  matrix.sliceCompressedRowsLengths.getData(),
+                  matrix.sliceCompressedRowLengths.getData(),
                   matrix.getPaddingIndex(),
                   matrix.columnIndexes.getData(),
                   matrix.values.getData(),
                   inVector.getData(),
                   outVector.getData(),
                   gridIdx );
-               checkCudaDevice;
+               TNL_CHECK_CUDA_DEVICE;
             }
             //Devices::Cuda::freeFromDevice( kernel_this );
             //Devices::Cuda::freeFromDevice( kernel_inVector );
             //Devices::Cuda::freeFromDevice( kernel_outVector );
-            checkCudaDevice;
+            TNL_CHECK_CUDA_DEVICE;
             cudaThreadSynchronize();
          #endif
       }
 
 };
 
+template<>
+class SlicedEllpackDeviceDependentCode< Devices::MIC >
+{
+   public:
+
+      typedef Devices::MIC Device;
+
+      template< typename Real,
+                typename Index,
+                int SliceSize >
+      static void initRowTraverse( const SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
+                                   const Index row,
+                                   Index& rowBegin,
+                                   Index& rowEnd,
+                                   Index& step )
+      {
+         throw std::runtime_error("Not Implemented yet SlicedEllpackDeviceDependentCode< Devices::MIC >::initRowTraverse");
+      }
+
+      template< typename Real,
+                typename Index,
+                int SliceSize >
+      __cuda_callable__
+      static void initRowTraverseFast( const SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
+                                       const Index row,
+                                       Index& rowBegin,
+                                       Index& rowEnd,
+                                       Index& step )
+      {
+         throw std::runtime_error("Not Implemented yet SlicedEllpackDeviceDependentCode< Devices::MIC >::initRowTraverseFast");
+      }
+
+      template< typename Real,
+                typename Index,
+                int SliceSize >
+            static bool computeMaximalRowLengthInSlices( SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
+                                                   const typename SlicedEllpack< Real, Device, Index >::CompressedRowLengthsVector& rowLengths )
+      {
+         throw std::runtime_error("Not Implemented yet SlicedEllpackDeviceDependentCode< Devices::MIC >::computeMaximalRowLengthInSlices");
+      }
+
+      template< typename Real,
+                typename Index,
+                typename InVector,
+                typename OutVector,
+                int SliceSize >
+      static void vectorProduct( const SlicedEllpack< Real, Device, Index, SliceSize >& matrix,
+                                 const InVector& inVector,
+                                 OutVector& outVector )
+      {
+         throw std::runtime_error("Not Implemented yet SlicedEllpackDeviceDependentCode< Devices::MIC >::vectorProduct");
+      }
+};
+
 } // namespace Matrices
 } // namespace TNL
diff --git a/src/TNL/Matrices/Sparse.h b/src/TNL/Matrices/Sparse.h
index 27a021f038eab6553924792aec2739d080253960..2a694826b94e9d757079f72942f3f810ce136885 100644
--- a/src/TNL/Matrices/Sparse.h
+++ b/src/TNL/Matrices/Sparse.h
@@ -26,7 +26,7 @@ class Sparse : public Matrix< Real, Device, Index >
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Matrix< RealType, DeviceType, IndexType >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Matrix< RealType, DeviceType, IndexType >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef typename Matrix< RealType, DeviceType, IndexType >::ValuesVector ValuesVector;
    typedef Containers::Vector< IndexType, DeviceType, IndexType > ColumnIndexesVector;
    typedef Matrix< Real, Device, Index > BaseType;
@@ -34,10 +34,10 @@ class Sparse : public Matrix< Real, Device, Index >
 
    Sparse();
 
-   virtual bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths ) = 0;
+   virtual void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths ) = 0;
 
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Sparse< Real2, Device2, Index2 >& matrix );
+   void setLike( const Sparse< Real2, Device2, Index2 >& matrix );
 
    IndexType getNumberOfMatrixElements() const;
 
@@ -58,13 +58,20 @@ class Sparse : public Matrix< Real, Device, Index >
 
    protected:
 
-   bool allocateMatrixElements( const IndexType& numberOfMatrixElements );
+   void allocateMatrixElements( const IndexType& numberOfMatrixElements );
 
    Containers::Vector< Index, Device, Index > columnIndexes;
 
    Index maxRowLength;
 };
 
+
+// This cannot be a method of the Sparse class, because the implementation uses
+// methods (marked with __cuda_callable__) which are defined only on the
+// subclasses, but are not virtual methods of Sparse.
+template< typename Matrix1, typename Matrix2 >
+void copySparseMatrix( Matrix1& A, const Matrix2& B );
+
 } // namespace Matrices
 } // namespace TNL
 
diff --git a/src/TNL/Matrices/SparseRow.h b/src/TNL/Matrices/SparseRow.h
index 8c4027532a4fd810050f80c4ffcbcb4e9cea60b6..c3a20762f22d3e580935872c964e5e87e0ad5333 100644
--- a/src/TNL/Matrices/SparseRow.h
+++ b/src/TNL/Matrices/SparseRow.h
@@ -11,6 +11,10 @@
 
 #pragma once
 
+#include <type_traits>
+
+#include <TNL/Devices/Cuda.h>
+
 namespace TNL {
 namespace Matrices {   
 
@@ -39,6 +43,12 @@ class SparseRow
                        const Index& column,
                        const Real& value );
  
+      __cuda_callable__
+      const Index& getElementColumn( const Index& elementIndex ) const;
+ 
+      __cuda_callable__
+      const Real& getElementValue( const Index& elementIndex ) const;
+ 
       void print( std::ostream& str ) const;
 
    protected:
diff --git a/src/TNL/Matrices/SparseRow_impl.h b/src/TNL/Matrices/SparseRow_impl.h
index 414ba822309418e5fbc2c216b957b59dcb20e15a..c4b69044bcd27268b3e6df8b53ab71ab379c9349 100644
--- a/src/TNL/Matrices/SparseRow_impl.h
+++ b/src/TNL/Matrices/SparseRow_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Matrices/SparseRow.h>
+
 namespace TNL {
 namespace Matrices {   
 
@@ -61,24 +63,49 @@ setElement( const Index& elementIndex,
             const Index& column,
             const Real& value )
 {
-   Assert( this->columns, );
-   Assert( this->values, );
-   Assert( this->step > 0,);
+   TNL_ASSERT( this->columns, );
+   TNL_ASSERT( this->values, );
+   TNL_ASSERT( this->step > 0,);
    //printf( "elementIndex = %d length = %d \n", elementIndex, this->length );
-   Assert( elementIndex >= 0 && elementIndex < this->length,
+   TNL_ASSERT( elementIndex >= 0 && elementIndex < this->length,
               std::cerr << "elementIndex = " << elementIndex << " this->length = " << this->length );
 
    this->columns[ elementIndex * step ] = column;
    this->values[ elementIndex * step ] = value;
 }
 
+template< typename Real, typename Index >
+__cuda_callable__
+const Index&
+SparseRow< Real, Index >::
+getElementColumn( const Index& elementIndex ) const
+{
+   TNL_ASSERT( elementIndex >= 0 && elementIndex < this->length,
+              std::cerr << "elementIndex = " << elementIndex << " this->length = " << this->length );
+
+   return this->columns[ elementIndex * step ];
+}
+
+template< typename Real, typename Index >
+__cuda_callable__
+const Real&
+SparseRow< Real, Index >::
+getElementValue( const Index& elementIndex ) const
+{
+   TNL_ASSERT( elementIndex >= 0 && elementIndex < this->length,
+              std::cerr << "elementIndex = " << elementIndex << " this->length = " << this->length );
+
+   return this->values[ elementIndex * step ];
+}
+
 template< typename Real, typename Index >
 void
 SparseRow< Real, Index >::
 print( std::ostream& str ) const
 {
-   Index pos( 0 );
-   for( Index i = 0; i < length; i++ )
+   using NonConstIndex = typename std::remove_const< Index >::type;
+   NonConstIndex pos( 0 );
+   for( NonConstIndex i = 0; i < length; i++ )
    {
       str << " [ " << columns[ pos ] << " ] = " << values[ pos ] << ", ";
       pos += step;
diff --git a/src/TNL/Matrices/Sparse_impl.h b/src/TNL/Matrices/Sparse_impl.h
index 4f415976a7306b512162272df8142c444b92e5e0..61b3b21d68e4488493431faf890afd5c2537a1fe 100644
--- a/src/TNL/Matrices/Sparse_impl.h
+++ b/src/TNL/Matrices/Sparse_impl.h
@@ -10,8 +10,11 @@
 
 #pragma once
 
+#include "Sparse.h"
+#include <TNL/DevicePointer.h>
+
 namespace TNL {
-namespace Matrices {   
+namespace Matrices {
 
 template< typename Real,
           typename Device,
@@ -27,12 +30,10 @@ template< typename Real,
    template< typename Real2,
              typename Device2,
              typename Index2 >
-bool Sparse< Real, Device, Index >::setLike( const Sparse< Real2, Device2, Index2 >& matrix )
+void Sparse< Real, Device, Index >::setLike( const Sparse< Real2, Device2, Index2 >& matrix )
 {
-   if( ! Matrix< Real, Device, Index >::setLike( matrix ) ||
-       ! this->allocateMatrixElements( matrix.getNumberOfMatrixElements() ) )
-      return false;
-   return true;
+   Matrix< Real, Device, Index >::setLike( matrix );
+   this->allocateMatrixElements( matrix.getNumberOfMatrixElements() );
 }
 
 template< typename Real,
@@ -112,18 +113,16 @@ bool Sparse< Real, Device, Index >::load( File& file )
 template< typename Real,
           typename Device,
           typename Index >
-bool Sparse< Real, Device, Index >::allocateMatrixElements( const IndexType& numberOfMatrixElements )
+void Sparse< Real, Device, Index >::allocateMatrixElements( const IndexType& numberOfMatrixElements )
 {
-   if( ! this->values.setSize( numberOfMatrixElements ) ||
-       ! this->columnIndexes.setSize( numberOfMatrixElements ) )
-      return false;
+   this->values.setSize( numberOfMatrixElements );
+   this->columnIndexes.setSize( numberOfMatrixElements );
 
    /****
     * Setting a column index to this->columns means that the
     * index is undefined.
     */
    this->columnIndexes.setValue( this->columns );
-   return true;
 }
 
 template< typename Real,
@@ -131,6 +130,147 @@ template< typename Real,
           typename Index >
 void Sparse< Real, Device, Index >::printStructure( std::ostream& str ) const
 {
+   TNL_ASSERT_TRUE( false, "Not implemented yet." );
+}
+
+
+#ifdef HAVE_CUDA
+template< typename Vector, typename Matrix >
+__global__ void
+SparseMatrixSetRowLengthsVectorKernel( Vector* rowLengths,
+                                       const Matrix* matrix,
+                                       typename Matrix::IndexType rows,
+                                       typename Matrix::IndexType cols )
+{
+   using IndexType = typename Matrix::IndexType;
+
+   IndexType rowIdx = blockIdx.x * blockDim.x + threadIdx.x;
+   const IndexType gridSize = blockDim.x * gridDim.x;
+
+   while( rowIdx < rows ) {
+      const auto max_length = matrix->getRowLengthFast( rowIdx );
+      const auto row = matrix->getRow( rowIdx );
+      IndexType length = 0;
+      for( IndexType c_j = 0; c_j < max_length; c_j++ )
+         if( row.getElementColumn( c_j ) < cols )
+            length++;
+         else
+            break;
+      rowLengths[ rowIdx ] = length;
+      rowIdx += gridSize;
+   }
+}
+
+template< typename Matrix1, typename Matrix2 >
+__global__ void
+SparseMatrixCopyKernel( Matrix1* A,
+                        const Matrix2* B,
+                        const typename Matrix2::IndexType* rowLengths,
+                        typename Matrix2::IndexType rows )
+{
+   using IndexType = typename Matrix2::IndexType;
+
+   IndexType rowIdx = blockIdx.x * blockDim.x + threadIdx.x;
+   const IndexType gridSize = blockDim.x * gridDim.x;
+
+   while( rowIdx < rows ) {
+      const auto length = rowLengths[ rowIdx ];
+      const auto rowB = B->getRow( rowIdx );
+      auto rowA = A->getRow( rowIdx );
+      for( IndexType c = 0; c < length; c++ )
+         rowA.setElement( c, rowB.getElementColumn( c ), rowB.getElementValue( c ) );
+      rowIdx += gridSize;
+   }
+}
+#endif
+
+template< typename Matrix1, typename Matrix2 >
+void
+copySparseMatrix( Matrix1& A, const Matrix2& B )
+{
+   static_assert( std::is_same< typename Matrix1::RealType, typename Matrix2::RealType >::value,
+                  "The matrices must have the same RealType." );
+   static_assert( std::is_same< typename Matrix1::DeviceType, typename Matrix2::DeviceType >::value,
+                  "The matrices must be allocated on the same device." );
+   static_assert( std::is_same< typename Matrix1::IndexType, typename Matrix2::IndexType >::value,
+                  "The matrices must have the same IndexType." );
+
+   using RealType = typename Matrix1::RealType;
+   using DeviceType = typename Matrix1::DeviceType;
+   using IndexType = typename Matrix1::IndexType;
+
+   const IndexType rows = B.getRows();
+   const IndexType cols = B.getColumns();
+
+   A.setDimensions( rows, cols );
+
+   if( std::is_same< DeviceType, Devices::Host >::value ) {
+      // set row lengths
+      typename Matrix1::CompressedRowLengthsVector rowLengths;
+      rowLengths.setSize( rows );
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( IndexType i = 0; i < rows; i++ ) {
+         const auto max_length = B.getRowLength( i );
+         const auto row = B.getRow( i );
+         IndexType length = 0;
+         for( IndexType c_j = 0; c_j < max_length; c_j++ )
+            if( row.getElementColumn( c_j ) < cols )
+               length++;
+            else
+               break;
+         rowLengths[ i ] = length;
+      }
+      A.setCompressedRowLengths( rowLengths );
+
+#ifdef HAVE_OPENMP
+#pragma omp parallel for if( Devices::Host::isOMPEnabled() )
+#endif
+      for( IndexType i = 0; i < rows; i++ ) {
+         const auto length = rowLengths[ i ];
+         const auto rowB = B.getRow( i );
+         auto rowA = A.getRow( i );
+         for( IndexType c = 0; c < length; c++ )
+            rowA.setElement( c, rowB.getElementColumn( c ), rowB.getElementValue( c ) );
+      }
+   }
+
+   if( std::is_same< DeviceType, Devices::Cuda >::value ) {
+#ifdef HAVE_CUDA
+      dim3 blockSize( 256 );
+      dim3 gridSize;
+      const IndexType desGridSize = 32 * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+      gridSize.x = min( desGridSize, Devices::Cuda::getNumberOfBlocks( rows, blockSize.x ) );
+
+      typename Matrix1::CompressedRowLengthsVector rowLengths;
+      rowLengths.setSize( rows );
+
+      DevicePointer< Matrix1 > Apointer( A );
+      const DevicePointer< const Matrix2 > Bpointer( B );
+
+      // set row lengths
+      Devices::Cuda::synchronizeDevice();
+      SparseMatrixSetRowLengthsVectorKernel<<< gridSize, blockSize >>>(
+            rowLengths.getData(),
+            &Bpointer.template getData< TNL::Devices::Cuda >(),
+            rows,
+            cols );
+      TNL_CHECK_CUDA_DEVICE;
+      Apointer->setCompressedRowLengths( rowLengths );
+
+      // copy rows
+      Devices::Cuda::synchronizeDevice();
+      SparseMatrixCopyKernel<<< gridSize, blockSize >>>(
+            &Apointer.template modifyData< TNL::Devices::Cuda >(),
+            &Bpointer.template getData< TNL::Devices::Cuda >(),
+            rowLengths.getData(),
+            rows );
+      TNL_CHECK_CUDA_DEVICE;
+#else
+      throw Exceptions::CudaSupportMissing();
+#endif
+   }
 }
 
 } // namespace Matrices
diff --git a/src/TNL/Matrices/Tridiagonal.h b/src/TNL/Matrices/Tridiagonal.h
index 5457f12f18053bc869640966958d703c31f99a4c..0769ca83f2f0355ee3ad4c726c601bd16bae8c3f 100644
--- a/src/TNL/Matrices/Tridiagonal.h
+++ b/src/TNL/Matrices/Tridiagonal.h
@@ -25,12 +25,20 @@ template< typename Real = double,
           typename Index = int >
 class Tridiagonal : public Matrix< Real, Device, Index >
 {
-   public:
+private:
+   // convenient template alias for controlling the selection of copy-assignment operator
+   template< typename Device2 >
+   using Enabler = std::enable_if< ! std::is_same< Device2, Device >::value >;
 
+   // friend class will be needed for templated assignment operators
+   template< typename Real2, typename Device2, typename Index2 >
+   friend class Tridiagonal;
+
+public:
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename Matrix< Real, Device, Index >::CompressedRowsLengthsVector CompressedRowsLengthsVector;
+   typedef typename Matrix< Real, Device, Index >::CompressedRowLengthsVector CompressedRowLengthsVector;
    typedef Tridiagonal< Real, Device, Index > ThisType;
    typedef Tridiagonal< Real, Devices::Host, Index > HostType;
    typedef Tridiagonal< Real, Devices::Cuda, Index > CudaType;
@@ -43,17 +51,24 @@ class Tridiagonal : public Matrix< Real, Device, Index >
 
    String getTypeVirtual() const;
 
-   bool setDimensions( const IndexType rows,
+   static String getSerializationType();
+
+   virtual String getSerializationTypeVirtual() const;
+
+   void setDimensions( const IndexType rows,
                        const IndexType columns );
 
-   bool setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths );
+   void setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths );
 
    IndexType getRowLength( const IndexType row ) const;
 
+   __cuda_callable__
+   IndexType getRowLengthFast( const IndexType row ) const;
+
    IndexType getMaxRowLength() const;
 
    template< typename Real2, typename Device2, typename Index2 >
-   bool setLike( const Tridiagonal< Real2, Device2, Index2 >& m );
+   void setLike( const Tridiagonal< Real2, Device2, Index2 >& m );
 
    IndexType getNumberOfMatrixElements() const;
 
@@ -148,15 +163,9 @@ class Tridiagonal : public Matrix< Real, Device, Index >
                    const RealType& matrixMultiplicator = 1.0,
                    const RealType& thisMatrixMultiplicator = 1.0 );
 
-#ifdef HAVE_NOT_CXX11
    template< typename Real2, typename Index2 >
    void getTransposition( const Tridiagonal< Real2, Device, Index2 >& matrix,
                           const RealType& matrixMultiplicator = 1.0 );
-#else
-   template< typename Real2, typename Index2 >
-   void getTransposition( const Tridiagonal< Real2, Device, Index2 >& matrix,
-                          const RealType& matrixMultiplicator = 1.0 );
-#endif
 
    template< typename Vector >
    __cuda_callable__
@@ -165,6 +174,14 @@ class Tridiagonal : public Matrix< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
+   // copy assignment
+   Tridiagonal& operator=( const Tridiagonal& matrix );
+
+   // cross-device copy assignment
+   template< typename Real2, typename Device2, typename Index2,
+             typename = typename Enabler< Device2 >::type >
+   Tridiagonal& operator=( const Tridiagonal< Real2, Device2, Index2 >& matrix );
+
    bool save( File& file ) const;
 
    bool load( File& file );
@@ -175,7 +192,7 @@ class Tridiagonal : public Matrix< Real, Device, Index >
 
    void print( std::ostream& str ) const;
 
-   protected:
+protected:
 
    __cuda_callable__
    IndexType getElementIndex( const IndexType row,
diff --git a/src/TNL/Matrices/TridiagonalRow_impl.h b/src/TNL/Matrices/TridiagonalRow_impl.h
index 09d173342f5578c867569c58b1688c5425ac572f..f5b7e842a4c4b69c77aa11f2ee09984eb46f9808 100644
--- a/src/TNL/Matrices/TridiagonalRow_impl.h
+++ b/src/TNL/Matrices/TridiagonalRow_impl.h
@@ -61,11 +61,11 @@ setElement( const Index& elementIndex,
             const Index& column,
             const Real& value )
 {
-   Assert( this->values, );
-   Assert( this->step > 0,);
-   Assert( column >= 0 && column < this->columns,
+   TNL_ASSERT( this->values, );
+   TNL_ASSERT( this->step > 0,);
+   TNL_ASSERT( column >= 0 && column < this->columns,
               std::cerr << "column = " << columns << " this->columns = " << this->columns );
-   Assert( abs( column - row ) <= 1,
+   TNL_ASSERT( abs( column - row ) <= 1,
               std::cerr << "column = " << column << " row =  " << row );
 
    /****
diff --git a/src/TNL/Matrices/Tridiagonal_impl.h b/src/TNL/Matrices/Tridiagonal_impl.h
index afd72d1cd658b69faa57049aa6f656bbacd95852..f3c073cd0d65285643df34d8fc2885e802c77e36 100644
--- a/src/TNL/Matrices/Tridiagonal_impl.h
+++ b/src/TNL/Matrices/Tridiagonal_impl.h
@@ -48,44 +48,65 @@ String Tridiagonal< Real, Device, Index >::getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-bool Tridiagonal< Real, Device, Index >::setDimensions( const IndexType rows,
-                                                                 const IndexType columns )
+String Tridiagonal< Real, Device, Index >::getSerializationType()
 {
-   if( ! Matrix< Real, Device, Index >::setDimensions( rows, columns ) )
-      return false;
-   if( ! values.setSize( 3*min( rows, columns ) ) )
-      return false;
+   return getType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+String Tridiagonal< Real, Device, Index >::getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+void Tridiagonal< Real, Device, Index >::setDimensions( const IndexType rows,
+                                                        const IndexType columns )
+{
+   Matrix< Real, Device, Index >::setDimensions( rows, columns );
+   values.setSize( 3*min( rows, columns ) );
    this->values.setValue( 0.0 );
-   return true;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Tridiagonal< Real, Device, Index >::setCompressedRowsLengths( const CompressedRowsLengthsVector& rowLengths )
+void Tridiagonal< Real, Device, Index >::setCompressedRowLengths( const CompressedRowLengthsVector& rowLengths )
 {
    if( rowLengths[ 0 ] > 2 )
-      return false;
+      throw std::logic_error( "Too many non-zero elements per row in a tri-diagonal matrix." );
    const IndexType diagonalLength = min( this->getRows(), this->getColumns() );
    for( Index i = 1; i < diagonalLength-1; i++ )
       if( rowLengths[ i ] > 3 )
-         return false;
+         throw std::logic_error( "Too many non-zero elements per row in a tri-diagonal matrix." );
    if( this->getRows() > this->getColumns() )
       if( rowLengths[ this->getRows()-1 ] > 1 )
-         return false;
+         throw std::logic_error( "Too many non-zero elements per row in a tri-diagonal matrix." );
    if( this->getRows() == this->getColumns() )
       if( rowLengths[ this->getRows()-1 ] > 2 )
-         return false;
+         throw std::logic_error( "Too many non-zero elements per row in a tri-diagonal matrix." );
    if( this->getRows() < this->getColumns() )
       if( rowLengths[ this->getRows()-1 ] > 3 )
-         return false;
-   return true;
+         throw std::logic_error( "Too many non-zero elements per row in a tri-diagonal matrix." );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 Index Tridiagonal< Real, Device, Index >::getRowLength( const IndexType row ) const
+{
+   return this->getRowLengthFast( row );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Index Tridiagonal< Real, Device, Index >::getRowLengthFast( const IndexType row ) const
 {
    const IndexType diagonalLength = min( this->getRows(), this->getColumns() );
    if( row == 0 )
@@ -111,9 +132,9 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename Real2, typename Device2, typename Index2 >
-bool Tridiagonal< Real, Device, Index >::setLike( const Tridiagonal< Real2, Device2, Index2 >& m )
+void Tridiagonal< Real, Device, Index >::setLike( const Tridiagonal< Real2, Device2, Index2 >& m )
 {
-   return this->setDimensions( m.getRows(), m.getColumns() );
+   this->setDimensions( m.getRows(), m.getColumns() );
 }
 
 template< typename Real,
@@ -240,7 +261,7 @@ bool Tridiagonal< Real, Device, Index >::setRowFast( const IndexType row,
                                                               const RealType* values,
                                                               const IndexType elements )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    return this->addRowFast( row, columns, values, elements, 0.0 );
@@ -254,7 +275,7 @@ bool Tridiagonal< Real, Device, Index >::setRow( const IndexType row,
                                                           const RealType* values,
                                                           const IndexType elements )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    return this->addRow( row, columns, values, elements, 0.0 );
@@ -270,7 +291,7 @@ bool Tridiagonal< Real, Device, Index >::addRowFast( const IndexType row,
                                                               const IndexType elements,
                                                               const RealType& thisRowMultiplicator )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    if( elements > 3 )
@@ -294,7 +315,7 @@ bool Tridiagonal< Real, Device, Index >::addRow( const IndexType row,
                                                           const IndexType elements,
                                                           const RealType& thisRowMultiplicator )
 {
-   Assert( elements <= this->columns,
+   TNL_ASSERT( elements <= this->columns,
             std::cerr << " elements = " << elements
                  << " this->columns = " << this->columns );
    if( elements > 3 )
@@ -381,7 +402,7 @@ const typename Tridiagonal< Real, Device, Index >::MatrixRow
 Tridiagonal< Real, Device, Index >::
 getRow( const IndexType rowIndex ) const
 {
-   Assert( false, );
+   TNL_ASSERT( false, );
 }
 
 
@@ -408,10 +429,10 @@ template< typename Real,
 void Tridiagonal< Real, Device, Index >::vectorProduct( const InVector& inVector,
                                                                  OutVector& outVector ) const
 {
-   Assert( this->getColumns() == inVector.getSize(),
+   TNL_ASSERT( this->getColumns() == inVector.getSize(),
             std::cerr << "Matrix columns: " << this->getColumns() << std::endl
                  << "Vector size: " << inVector.getSize() << std::endl );
-   Assert( this->getRows() == outVector.getSize(),
+   TNL_ASSERT( this->getRows() == outVector.getSize(),
                std::cerr << "Matrix rows: " << this->getRows() << std::endl
                     << "Vector size: " << outVector.getSize() << std::endl );
 
@@ -426,7 +447,7 @@ void Tridiagonal< Real, Device, Index >::addMatrix( const Tridiagonal< Real2, De
                                                              const RealType& matrixMultiplicator,
                                                              const RealType& thisMatrixMultiplicator )
 {
-   Assert( this->getRows() == matrix.getRows(),
+   TNL_ASSERT( this->getRows() == matrix.getRows(),
             std::cerr << "This matrix columns: " << this->getColumns() << std::endl
                  << "This matrix rows: " << this->getRows() << std::endl );
 
@@ -471,7 +492,7 @@ template< typename Real,
 void Tridiagonal< Real, Device, Index >::getTransposition( const Tridiagonal< Real2, Device, Index2 >& matrix,
                                                                     const RealType& matrixMultiplicator )
 {
-   Assert( this->getRows() == matrix.getRows(),
+   TNL_ASSERT( this->getRows() == matrix.getRows(),
                std::cerr << "This matrix rows: " << this->getRows() << std::endl
                     << "That matrix rows: " << matrix.getRows() << std::endl );
    if( std::is_same< Device, Devices::Host >::value )
@@ -506,7 +527,7 @@ void Tridiagonal< Real, Device, Index >::getTransposition( const Tridiagonal< Re
       }
       Devices::Cuda::freeFromDevice( kernel_this );
       Devices::Cuda::freeFromDevice( kernel_inMatrix );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
 #endif
    }
 }
@@ -529,6 +550,39 @@ void Tridiagonal< Real, Device, Index >::performSORIteration( const Vector& b,
    x[ row ] = ( 1.0 - omega ) * x[ row ] + omega / this->getElementFast( row, row ) * ( b[ row ] - sum );
 }
 
+
+// copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+Tridiagonal< Real, Device, Index >&
+Tridiagonal< Real, Device, Index >::operator=( const Tridiagonal& matrix )
+{
+   this->setLike( matrix );
+   this->values = matrix.values;
+   return *this;
+}
+
+// cross-device copy assignment
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename Real2, typename Device2, typename Index2, typename >
+Tridiagonal< Real, Device, Index >&
+Tridiagonal< Real, Device, Index >::operator=( const Tridiagonal< Real2, Device2, Index2 >& matrix )
+{
+   static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value,
+                  "unknown device" );
+   static_assert( std::is_same< Device2, Devices::Host >::value || std::is_same< Device2, Devices::Cuda >::value,
+                  "unknown device" );
+
+   this->setLike( matrix );
+
+   std::cerr << "Cross-device assignment for the Tridiagonal format is not implemented yet." << std::endl;
+   throw 1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -595,10 +649,10 @@ __cuda_callable__
 Index Tridiagonal< Real, Device, Index >::getElementIndex( const IndexType row,
                                                                     const IndexType column ) const
 {
-   Assert( row >= 0 && column >= 0 && row < this->rows && column < this->rows,
+   TNL_ASSERT( row >= 0 && column >= 0 && row < this->rows && column < this->rows,
               std::cerr << " this->rows = " << this->rows
                    << " row = " << row << " column = " << column );
-   Assert( abs( row - column ) < 2,
+   TNL_ASSERT( abs( row - column ) < 2,
               std::cerr << "row = " << row << " column = " << column << std::endl );
    return TridiagonalDeviceDependentCode< Device >::getElementIndex( this->rows, row, column );
 }
diff --git a/src/TNL/Meshes/CMakeLists.txt b/src/TNL/Meshes/CMakeLists.txt
old mode 100755
new mode 100644
index b97985a544941ef4a3107ba38a8cd4e1259d414a..b06294793cbe0f662d9c07e2002930e1cdc03fdc
--- a/src/TNL/Meshes/CMakeLists.txt
+++ b/src/TNL/Meshes/CMakeLists.txt
@@ -6,7 +6,7 @@ SET( headers Grid.h
              GridEntity.h
              GridEntityConfig.h
              DummyMesh.h
-             MeshDimensionsTag.h             
+             MeshDimensionTag.h             
              Mesh.h
              MeshEntity.h
              Traverser.h
diff --git a/src/TNL/Meshes/DummyMesh.h b/src/TNL/Meshes/DummyMesh.h
index 3b57ed34905a8929c3a52c7246c29eb490bff9f0..ce4cd0bf42f92d8911fa482ca240e5e919ba00e1 100644
--- a/src/TNL/Meshes/DummyMesh.h
+++ b/src/TNL/Meshes/DummyMesh.h
@@ -25,10 +25,7 @@ class DummyMesh
    typedef Index IndexType;
    typedef DummyMesh< Real, Device, Index > ThisType;
  
-   static const int meshDimensions = 1;
- 
-   constexpr static int getMeshDimensions() { return meshDimensions; }
- 
+   constexpr static int getMeshDimension() { return 1; }
  
    const Real& getParametricStep(){ return 0.0; }
  
diff --git a/src/TNL/Meshes/Grid.h b/src/TNL/Meshes/Grid.h
index d5966b033e582c32633d03c4aa0a4a05ae870155..07053991262385c8fd19e72377693c6748fc84de 100644
--- a/src/TNL/Meshes/Grid.h
+++ b/src/TNL/Meshes/Grid.h
@@ -18,7 +18,7 @@
 namespace TNL {
 namespace Meshes {
 
-template< int Dimensions,
+template< int Dimension,
           typename Real = double,
           typename Device = Devices::Host,
           typename Index = int >
diff --git a/src/TNL/Meshes/GridDetails/CMakeLists.txt b/src/TNL/Meshes/GridDetails/CMakeLists.txt
index 7e39623121c8dba1ee95332a69fada92a561bbd5..eeecd7bc50bbbac8492066be8f7bf9bf20b19e4d 100644
--- a/src/TNL/Meshes/GridDetails/CMakeLists.txt
+++ b/src/TNL/Meshes/GridDetails/CMakeLists.txt
@@ -15,11 +15,11 @@ SET( headers BoundaryGridEntityChecker.h
              GridEntityTopology.h
              GridTraverser.h
              GridTraverser_impl.h
-             NeighbourGridEntitiesStorage.h
-             NeighbourGridEntityGetter1D_impl.h
-             NeighbourGridEntityGetter2D_impl.h
-             NeighbourGridEntityGetter3D_impl.h
-             NeighbourGridEntityGetter.h
+             NeighborGridEntitiesStorage.h
+             NeighborGridEntityGetter1D_impl.h
+             NeighborGridEntityGetter2D_impl.h
+             NeighborGridEntityGetter3D_impl.h
+             NeighborGridEntityGetter.h
              Traverser_Grid1D.h
              Traverser_Grid1D_impl.h
              Traverser_Grid2D.h
diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h
index 2a78a73df331e209d1242293ca626b26a4e8be5e..ff9d13ccb827a9d725b373c0710691432e5f0e54 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D.h
@@ -14,7 +14,7 @@
 #include <TNL/Logger.h>
 #include <TNL/Meshes/GridDetails/GridEntityTopology.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 #include <TNL/Meshes/GridEntity.h>
 #include <TNL/Meshes/GridEntityConfig.h>
 
@@ -30,25 +30,26 @@ class Grid< 1, Real, Device, Index > : public Object
 
    typedef Real RealType;
    typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef Containers::StaticVector< 1, Real > VertexType;
+   typedef Index GlobalIndexType;
+   typedef Containers::StaticVector< 1, Real > PointType;
    typedef Containers::StaticVector< 1, Index > CoordinatesType;
    typedef Grid< 1, Real, Devices::Host, Index > HostType;
    typedef Grid< 1, Real, Devices::Cuda, Index > CudaType;
    typedef Grid< 1, Real, Device, Index > ThisType;
+
+   // TODO: deprecated and to be removed (GlobalIndexType shall be used instead)
+   typedef Index IndexType;
  
-   static const int meshDimensions = 1;
+   static constexpr int getMeshDimension() { return 1; };
  
-   template< int EntityDimensions,
+   template< int EntityDimension,
              typename Config = GridEntityCrossStencilStorage< 1 > >
-   using MeshEntity = GridEntity< ThisType, EntityDimensions, Config >;
+   using EntityType = GridEntity< ThisType, EntityDimension, Config >;
  
-   typedef MeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
-   typedef MeshEntity< 0 > Face;
-   typedef MeshEntity< 0 > Vertex;
+   typedef EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > > Cell;
+   typedef EntityType< 0 > Face;
+   typedef EntityType< 0 > Vertex;
 
-   static constexpr int getMeshDimensions() { return meshDimensions; };
- 
    Grid();
 
    static String getType();
@@ -63,43 +64,44 @@ class Grid< 1, Real, Device, Index > : public Object
 
    void setDimensions( const CoordinatesType& dimensions );
 
-   __cuda_callable__ inline
+   __cuda_callable__
    const CoordinatesType& getDimensions() const;
 
-   void setDomain( const VertexType& origin,
-                   const VertexType& proportions );
+   void setDomain( const PointType& origin,
+                   const PointType& proportions );
 
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   inline const PointType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
- 
-   template< typename EntityType >
-   __cuda_callable__
-   inline IndexType getEntitiesCount() const;
+   inline const PointType& getProportions() const;
  
-   template< typename EntityType >
+
+   template< int EntiytDimension >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
- 
-   template< typename EntityType >
+   IndexType getEntitiesCount() const;
+
+   template< typename Entity >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
- 
-   template< typename EntityType >
+   IndexType getEntitiesCount() const;
+   
+   template< typename Entity >
    __cuda_callable__
-   RealType getEntityMeasure( const EntityType& entity ) const;
+   inline Entity getEntity( const IndexType& entityIndex ) const;
  
+   template< typename Entity >
    __cuda_callable__
-   inline const RealType& getCellMeasure() const;
+   inline Index getEntityIndex( const Entity& entity ) const;
  
    __cuda_callable__
-   inline VertexType getSpaceSteps() const;
+   inline const PointType& getSpaceSteps() const;
 
    template< int xPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
+   const RealType& getSpaceStepsProducts() const;
+   
+   __cuda_callable__
+   inline const RealType& getCellMeasure() const;
  
    __cuda_callable__
    inline RealType getSmallestSpaceStep() const;
@@ -146,9 +148,9 @@ class Grid< 1, Real, Device, Index > : public Object
  
    IndexType numberOfCells, numberOfVertices;
 
-   VertexType origin, proportions;
+   PointType origin, proportions;
  
-   VertexType spaceSteps;
+   PointType spaceSteps;
  
    RealType spaceStepsProducts[ 5 ];
 };
diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
index 8103d5b20b6fe5d54ab183f09da1bd4427e155ab..4c6d10ffc02b428d2d6d700a42d66c6aaa0ad775 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
@@ -14,9 +14,10 @@
 #include <iomanip>
 #include <TNL/String.h>
 #include <TNL/Assert.h>
+#include <TNL/Logger.h>
 #include <TNL/Meshes/GridDetails/GnuplotWriter.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter_impl.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter1D_impl.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h>
 #include <TNL/Meshes/GridDetails/Grid1D.h>
 #include <TNL/Meshes/GridDetails/GridEntityMeasureGetter.h>
 
@@ -38,7 +39,7 @@ template< typename Real,
 String Grid< 1, Real, Device, Index >::getType()
 {
    return String( "Meshes::Grid< " ) +
-          String( getMeshDimensions() ) + ", " +
+          String( getMeshDimension() ) + ", " +
           String( TNL::getType< RealType >() ) + ", " +
           String( Device::getDeviceType() ) + ", " +
           String( TNL::getType< IndexType >() ) + " >";
@@ -90,7 +91,7 @@ template< typename Real,
           typename Index  >
 void Grid< 1, Real, Device, Index >::setDimensions( const Index xSize )
 {
-   Assert( xSize > 0, std::cerr << "xSize = " << xSize );
+   TNL_ASSERT_GT( xSize, 0, "Grid size must be positive." );
    this->dimensions.x() = xSize;
    this->numberOfCells = xSize;
    this->numberOfVertices = xSize + 1;
@@ -118,8 +119,8 @@ const typename Grid< 1, Real, Device, Index >::CoordinatesType&
 template< typename Real,
           typename Device,
           typename Index >
-void Grid< 1, Real, Device, Index >::setDomain( const VertexType& origin,
-                                                     const VertexType& proportions )
+void Grid< 1, Real, Device, Index >::setDomain( const PointType& origin,
+                                                     const PointType& proportions )
 {
    this->origin = origin;
    this->proportions = proportions;
@@ -130,7 +131,7 @@ template< typename Real,
           typename Device,
           typename Index  >
 __cuda_callable__ inline
-const typename Grid< 1, Real, Device, Index >::VertexType&
+const typename Grid< 1, Real, Device, Index >::PointType&
   Grid< 1, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
@@ -140,25 +141,26 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename Grid< 1, Real, Device, Index >::VertexType&
+const typename Grid< 1, Real, Device, Index >::PointType&
    Grid< 1, Real, Device, Index >::getProportions() const
 {
    return this->proportions;
 }
 
+
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
+   template< int EntityDimension >
 __cuda_callable__  inline
 Index
 Grid< 1, Real, Device, Index >::
 getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 1 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityDimension <= 1 &&
+                  EntityDimension >= 0, "Wrong grid entity dimensions." );
  
-   switch( EntityType::entityDimensions )
+   switch( EntityDimension )
    {
       case 1:
          return this->numberOfCells;
@@ -171,79 +173,78 @@ getEntitiesCount() const
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
- __cuda_callable__ inline
-EntityType
+   template< typename Entity >
+__cuda_callable__  inline
+Index
 Grid< 1, Real, Device, Index >::
-getEntity( const IndexType& entityIndex ) const
+getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 1 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
- 
-   return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex );
+   return getEntitiesCount< Entity::getEntityDimension() >();
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
-__cuda_callable__ inline
-Index
+   template< typename Entity >
+ __cuda_callable__ inline
+Entity
 Grid< 1, Real, Device, Index >::
-getEntityIndex( const EntityType& entity ) const
+getEntity( const IndexType& entityIndex ) const
 {
-   static_assert( EntityType::entityDimensions <= 1 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( Entity::getEntityDimension() <= 1 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
  
-   return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
+   return GridEntityGetter< ThisType, Entity >::getEntity( *this, entityIndex );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
-__cuda_callable__
-Real
+   template< typename Entity >
+__cuda_callable__ inline
+Index
 Grid< 1, Real, Device, Index >::
-getEntityMeasure( const EntityType& entity ) const
+getEntityIndex( const Entity& entity ) const
 {
-   return GridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+   static_assert( Entity::getEntityDimension() <= 1 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
+ 
+   return GridEntityGetter< ThisType, Entity >::getEntityIndex( *this, entity );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__
-const Real&
+__cuda_callable__ inline
+const typename Grid< 1, Real, Device, Index >::PointType&
 Grid< 1, Real, Device, Index >::
-getCellMeasure() const
+getSpaceSteps() const
 {
-   return this->template getSpaceStepsProducts< 1 >();
+   return this->spaceSteps;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
+   template< int xPow >
 __cuda_callable__ inline
-typename Grid< 1, Real, Device, Index >::VertexType
+const Real&
 Grid< 1, Real, Device, Index >::
-getSpaceSteps() const
+getSpaceStepsProducts() const
 {
-   return this->spaceSteps;
+   static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" );
+   return this->spaceStepsProducts[ xPow + 2 ];
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< int xPow >
-__cuda_callable__ inline
+__cuda_callable__
 const Real&
 Grid< 1, Real, Device, Index >::
-getSpaceStepsProducts() const
+getCellMeasure() const
 {
-   Assert( xPow >= -2 && xPow <= 2,
-              std::cerr << " xPow = " << xPow );
-   return this->spaceStepsProducts[ xPow + 2 ];
+   return this->template getSpaceStepsProducts< 1 >();
 }
 
 template< typename Real,
@@ -391,12 +392,12 @@ bool Grid< 1, Real, Device, Index >::write( const MeshFunction& function,
    const RealType hx = getSpaceSteps(). x();
    if( format == "gnuplot" )
    {
-      typename ThisType::template MeshEntity< getMeshDimensions() > entity( *this );
+      typename ThisType::template EntityType< getMeshDimension() > entity( *this );
       for( entity.getCoordinates().x() = 0;
            entity.getCoordinates().x() < getDimensions(). x();
            entity.getCoordinates().x() ++ )
       {
-         VertexType v = entity.getCenter();
+         PointType v = entity.getCenter();
          GnuplotWriter::write( file,  v );
          GnuplotWriter::write( file,  function[ this->getEntityIndex( entity ) ] );
          file << std::endl;
@@ -413,11 +414,13 @@ void
 Grid< 1, Real, Device, Index >::
 writeProlog( Logger& logger )
 {
-   logger.writeParameter( "Dimensions:", getMeshDimensions() );
+   logger.writeParameter( "Dimension:", getMeshDimension() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
    logger.writeParameter( "Space steps:", this->getSpaceSteps() );
+   logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() );
+   logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() );
 }
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h
index b4d69458f96a73ec9b77fad35b978254ac3a1ce5..e893b3e24e7ba3c1230d1b11e6eb65f8102d5678 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D.h
@@ -11,9 +11,10 @@
 #pragma once
 
 #include <TNL/Meshes/Grid.h>
+#include <TNL/Meshes/GridEntity.h>
 #include <TNL/Meshes/GridDetails/GridEntityTopology.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 
 namespace TNL {
 namespace Meshes {
@@ -27,33 +28,34 @@ class Grid< 2, Real, Device, Index > : public Object
 
    typedef Real RealType;
    typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef Containers::StaticVector< 2, Real > VertexType;
+   typedef Index GlobalIndexType;
+   typedef Containers::StaticVector< 2, Real > PointType;
    typedef Containers::StaticVector< 2, Index > CoordinatesType;
    typedef Grid< 2, Real, Devices::Host, Index > HostType;
    typedef Grid< 2, Real, Devices::Cuda, Index > CudaType;
    typedef Grid< 2, Real, Device, Index > ThisType;
  
-   static const int meshDimensions = 2;
+   // TODO: deprecated and to be removed (GlobalIndexType shall be used instead)
+   typedef Index IndexType;
+ 
+   static constexpr int getMeshDimension() { return 2; };
 
-   template< int EntityDimensions,
+   template< int EntityDimension,
              typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   using MeshEntity = GridEntity< ThisType, EntityDimensions, Config >;
+   using EntityType = GridEntity< ThisType, EntityDimension, Config >;
  
-   typedef MeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
-   typedef MeshEntity< meshDimensions - 1, GridEntityNoStencilStorage > Face;
-   typedef MeshEntity< 0 > Vertex;
+   typedef EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > > Cell;
+   typedef EntityType< getMeshDimension() - 1, GridEntityNoStencilStorage > Face;
+   typedef EntityType< 0 > Vertex;
    
 
    // TODO: remove this
-   //template< int EntityDimensions, 
+   //template< int EntityDimension, 
    //          typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   //using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimensions, Config >;
-   //typedef TestMeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > TestCell;
+   //using TestEntityType = tnlTestGridEntity< ThisType, EntityDimension, Config >;
+   //typedef TestEntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > > TestCell;
    /////
    
-   static constexpr int getMeshDimensions() { return meshDimensions; };
-
    Grid();
 
    static String getType();
@@ -69,41 +71,42 @@ class Grid< 2, Real, Device, Index > : public Object
    void setDimensions( const CoordinatesType& dimensions );
 
    __cuda_callable__
-   inline const CoordinatesType& getDimensions() const;
+   const CoordinatesType& getDimensions() const;
 
-   void setDomain( const VertexType& origin,
-                   const VertexType& proportions );
+   void setDomain( const PointType& origin,
+                   const PointType& proportions );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   inline const PointType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   inline const PointType& getProportions() const;
 
-   template< typename EntityType >
+
+   template< int EntityDimension >
+   __cuda_callable__
+   IndexType getEntitiesCount() const;
+   
+   template< typename Entity >
    __cuda_callable__
    inline IndexType getEntitiesCount() const;
  
-   template< typename EntityType >
+   template< typename Entity >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
+   inline Entity getEntity( const IndexType& entityIndex ) const;
  
-   template< typename EntityType >
+   template< typename Entity >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
+   inline Index getEntityIndex( const Entity& entity ) const;
 
-   template< typename EntityType >
    __cuda_callable__
-   RealType getEntityMeasure( const EntityType& entity ) const;
- 
-   __cuda_callable__
-   inline const RealType& getCellMeasure() const;
- 
-   __cuda_callable__
-   inline VertexType getSpaceSteps() const;
+   inline const PointType& getSpaceSteps() const;
 
    template< int xPow, int yPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
+   const RealType& getSpaceStepsProducts() const;
+   
+   __cuda_callable__
+   inline const RealType& getCellMeasure() const;
  
    __cuda_callable__
    inline RealType getSmallestSpaceStep() const;
@@ -154,9 +157,9 @@ class Grid< 2, Real, Device, Index > : public Object
  
    IndexType numberOfCells, numberOfNxFaces, numberOfNyFaces, numberOfFaces, numberOfVertices;
 
-   VertexType origin, proportions;
+   PointType origin, proportions;
  
-   VertexType spaceSteps;
+   PointType spaceSteps;
  
    RealType spaceStepsProducts[ 5 ][ 5 ];
  
diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
index b888298ae2696305f9978d3f6d100b2178ed89f2..74c98aa8eb2f60a52e1b730f6fbb8874855f0838 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
@@ -12,10 +12,13 @@
 
 #include <fstream>
 #include <iomanip>
+#include <TNL/String.h>
 #include <TNL/Assert.h>
+#include <TNL/Logger.h>
 #include <TNL/Meshes/GridDetails/GnuplotWriter.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter_impl.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter2D_impl.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h>
+#include <TNL/Meshes/GridDetails/Grid2D.h>
 #include <TNL/Meshes/GridDetails/GridEntityMeasureGetter.h>
 
 namespace TNL {
@@ -39,7 +42,7 @@ template< typename Real,
 String Grid< 2, Real, Device, Index > :: getType()
 {
    return String( "Meshes::Grid< " ) +
-          String( getMeshDimensions() ) + ", " +
+          String( getMeshDimension() ) + ", " +
           String( TNL::getType< RealType >() ) + ", " +
           String( Device :: getDeviceType() ) + ", " +
           String( TNL::getType< IndexType >() ) + " >";
@@ -134,8 +137,8 @@ template< typename Real,
           typename Index >
 void Grid< 2, Real, Device, Index > :: setDimensions( const Index xSize, const Index ySize )
 {
-   Assert( xSize > 0, std::cerr << "xSize = " << xSize );
-   Assert( ySize > 0, std::cerr << "ySize = " << ySize );
+   TNL_ASSERT_GT( xSize, 0, "Grid size must be positive." );
+   TNL_ASSERT_GT( ySize, 0, "Grid size must be positive." );
 
    this->dimensions.x() = xSize;
    this->dimensions.y() = ySize;
@@ -168,8 +171,8 @@ Grid< 2, Real, Device, Index > :: getDimensions() const
 template< typename Real,
           typename Device,
           typename Index >
-void Grid< 2, Real, Device, Index > :: setDomain( const VertexType& origin,
-                                                     const VertexType& proportions )
+void Grid< 2, Real, Device, Index > :: setDomain( const PointType& origin,
+                                                     const PointType& proportions )
 {
    this->origin = origin;
    this->proportions = proportions;
@@ -180,7 +183,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename Grid< 2, Real, Device, Index >::VertexType&
+const typename Grid< 2, Real, Device, Index >::PointType&
 Grid< 2, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
@@ -190,25 +193,26 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename Grid< 2, Real, Device, Index > :: VertexType&
+const typename Grid< 2, Real, Device, Index > :: PointType&
    Grid< 2, Real, Device, Index > :: getProportions() const
 {
    return this->proportions;
 }
 
+
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
+   template< int EntityDimension >
 __cuda_callable__ inline
 Index
 Grid< 2, Real, Device, Index >::
 getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityDimension <= 2 &&
+                  EntityDimension >= 0, "Wrong grid entity dimensions." );
  
-   switch( EntityType::entityDimensions )
+   switch( EntityDimension )
    {
       case 2:
          return this->numberOfCells;
@@ -223,83 +227,79 @@ getEntitiesCount() const
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
+   template< typename Entity >
 __cuda_callable__ inline
-EntityType
+Index
 Grid< 2, Real, Device, Index >::
-getEntity( const IndexType& entityIndex ) const
+getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
- 
-   return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex );
+   return getEntitiesCount< Entity::getEntityDimension() >();
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
+   template< typename Entity >
 __cuda_callable__ inline
-Index
+Entity
 Grid< 2, Real, Device, Index >::
-getEntityIndex( const EntityType& entity ) const
+getEntity( const IndexType& entityIndex ) const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( Entity::getEntityDimension() <= 2 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
  
-   return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
+   return GridEntityGetter< ThisType, Entity >::getEntity( *this, entityIndex );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
-__cuda_callable__
-Real
+   template< typename Entity >
+__cuda_callable__ inline
+Index
 Grid< 2, Real, Device, Index >::
-getEntityMeasure( const EntityType& entity ) const
+getEntityIndex( const Entity& entity ) const
 {
-   return GridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+   static_assert( Entity::getEntityDimension() <= 2 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
+ 
+   return GridEntityGetter< ThisType, Entity >::getEntityIndex( *this, entity );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__
-const Real&
+__cuda_callable__ inline
+const typename Grid< 2, Real, Device, Index >::PointType&
 Grid< 2, Real, Device, Index >::
-getCellMeasure() const
+getSpaceSteps() const
 {
-   return this->template getSpaceStepsProducts< 1, 1 >();
+   return this->spaceSteps;
 }
 
-
 template< typename Real,
           typename Device,
           typename Index >
+   template< int xPow, int yPow  >
 __cuda_callable__ inline
-typename Grid< 2, Real, Device, Index >::VertexType
+const Real&
 Grid< 2, Real, Device, Index >::
-getSpaceSteps() const
+getSpaceStepsProducts() const
 {
-   return this->spaceSteps;
+   static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" );
+   static_assert( yPow >= -2 && yPow <= 2, "unsupported value of yPow" );
+   return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ];
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< int xPow, int yPow  >
-__cuda_callable__ inline
+__cuda_callable__
 const Real&
 Grid< 2, Real, Device, Index >::
-getSpaceStepsProducts() const
+getCellMeasure() const
 {
-   Assert( xPow >= -2 && xPow <= 2,
-              std::cerr << " xPow = " << xPow );
-   Assert( yPow >= -2 && yPow <= 2,
-              std::cerr << " yPow = " << yPow );
-
-   return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ];
+   return this->template getSpaceStepsProducts< 1, 1 >();
 }
 
 template< typename Real,
@@ -452,9 +452,9 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
            << this->getProportions(). x() << "cm , "
            << this->getProportions(). y() << "cm );"
            << std::endl << std::endl;
-      MeshEntity< 0 > vertex( *this );
+      Vertex vertex( *this );
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
-      VertexType v;
+      PointType v;
       for( Index j = 0; j < this->dimensions. y(); j ++ )
       {
          file << "draw( ";
@@ -490,7 +490,7 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
       }
       file << std::endl;
 
-      MeshEntity< 2 > cell( *this );
+      Cell cell( *this );
       CoordinatesType& cellCoordinates = cell.getCoordinates();
       const RealType cellMeasure = this->getSpaceSteps().x() * this->getSpaceSteps().y();
       for( Index i = 0; i < this->dimensions. x(); i ++ )
@@ -506,13 +506,13 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
       for( Index i = 0; i < this->dimensions. x(); i ++ )
          for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
-            VertexType v1, v2, c;
+            PointType 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->getPoint( CoordinatesType( i + 1, j ), v1 );
+            v2 = this->getPoint( CoordinatesType( i + 1, j + 1 ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -522,8 +522,8 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
             /****
              * West edge normal
              */
-            /*this->getVertex< -1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< -1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< -1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -533,8 +533,8 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
             /****
              * North edge normal
              */
-            /*this->getVertex< 1, 1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, 1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, 1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -544,8 +544,8 @@ bool Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
             /****
              * South edge normal
              */
-            /*this->getVertex< 1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, -1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, -1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, -1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -589,7 +589,7 @@ bool Grid< 2, Real, Device, Index > :: write( const MeshFunction& function,
       {
          for( cellCoordinates.x() = 0; cellCoordinates.x() < getDimensions(). x(); cellCoordinates.x() ++ )
          {
-            VertexType v = cell.getCenter();
+            PointType v = cell.getCenter();
             GnuplotWriter::write( file,  v );
             GnuplotWriter::write( file,  function[ this->getEntityIndex( cell ) ] );
             file << std::endl;
@@ -608,11 +608,14 @@ void
 Grid< 2, Real, Device, Index >::
 writeProlog( Logger& logger )
 {
-   logger.writeParameter( "Dimensions:", getMeshDimensions() );
+   logger.writeParameter( "Dimension:", getMeshDimension() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
    logger.writeParameter( "Space steps:", this->getSpaceSteps() );
+   logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() );
+   logger.writeParameter( "Number of faces:", getEntitiesCount< Face >() );
+   logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() );
 }
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h
index 84e326996a95481f140e583e1295fa06997d899b..2321d888fa557abaab05fd5f0deec0bb5aceb99f 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D.h
@@ -11,9 +11,10 @@
 #pragma once
 
 #include <TNL/Meshes/Grid.h>
+#include <TNL/Meshes/GridEntity.h>
 #include <TNL/Meshes/GridDetails/GridEntityTopology.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 
 namespace TNL {
 namespace Meshes {
@@ -27,25 +28,26 @@ class Grid< 3, Real, Device, Index > : public Object
 
    typedef Real RealType;
    typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef Containers::StaticVector< 3, Real > VertexType;
+   typedef Index GlobalIndexType;
+   typedef Containers::StaticVector< 3, Real > PointType;
    typedef Containers::StaticVector< 3, Index > CoordinatesType;
    typedef Grid< 3, Real, Devices::Host, Index > HostType;
    typedef Grid< 3, Real, Devices::Cuda, Index > CudaType;
    typedef Grid< 3, Real, Device, Index > ThisType;
  
-   static const int meshDimensions = 3;
+   // TODO: deprecated and to be removed (GlobalIndexType shall be used instead)
+   typedef Index IndexType;
+ 
+   static constexpr int getMeshDimension() { return 3; };
 
-   template< int EntityDimensions,
+   template< int EntityDimension,
              typename Config = GridEntityCrossStencilStorage< 1 > >
-   using MeshEntity = GridEntity< ThisType, EntityDimensions, Config >;
-
-   typedef MeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
-   typedef MeshEntity< meshDimensions - 1 > Face;
-   typedef MeshEntity< 1 > Edge;
-   typedef MeshEntity< 0 > Vertex;
+   using EntityType = GridEntity< ThisType, EntityDimension, Config >;
 
-   static constexpr int getMeshDimensions() { return meshDimensions; };
+   typedef EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > > Cell;
+   typedef EntityType< getMeshDimension() - 1 > Face;
+   typedef EntityType< 1 > Edge;
+   typedef EntityType< 0 > Vertex;
 
    Grid();
 
@@ -62,46 +64,47 @@ class Grid< 3, Real, Device, Index > : public Object
    void setDimensions( const CoordinatesType& );
 
    __cuda_callable__
-   inline const CoordinatesType& getDimensions() const;
+   const CoordinatesType& getDimensions() const;
 
-   void setDomain( const VertexType& origin,
-                   const VertexType& proportions );
+   void setDomain( const PointType& origin,
+                   const PointType& proportions );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   inline const PointType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   inline const PointType& getProportions() const;
 
-   template< typename EntityType >
+
+   template< int EntityDimension >
    __cuda_callable__
-   inline IndexType getEntitiesCount() const;
- 
-   template< typename EntityType >
+   IndexType getEntitiesCount() const;
+
+   template< typename Entity >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
- 
-   template< typename EntityType >
+   IndexType getEntitiesCount() const;
+
+   template< typename Entity >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
+   inline Entity getEntity( const IndexType& entityIndex ) const;
  
-   template< typename EntityType >
+   template< typename Entity >
    __cuda_callable__
-   RealType getEntityMeasure( const EntityType& entity ) const;
+   inline Index getEntityIndex( const Entity& entity ) const;
  
    __cuda_callable__
-   inline const RealType& getCellMeasure() const;
-
-   __cuda_callable__
-   inline VertexType getSpaceSteps() const;
+   inline const PointType& getSpaceSteps() const;
  
    template< int xPow, int yPow, int zPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
+   const RealType& getSpaceStepsProducts() const;
 
- 
    __cuda_callable__
-   inline RealType getSmallestSpaceStep() const;
+   inline const RealType& getCellMeasure() const;
+
  
+   __cuda_callable__
+   RealType getSmallestSpaceStep() const;
+      
    template< typename GridFunction >
    typename GridFunction::RealType getAbsMax( const GridFunction& f ) const;
 
@@ -149,11 +152,11 @@ class Grid< 3, Real, Device, Index > : public Object
           numberOfDxEdges, numberOfDyEdges, numberOfDzEdges, numberOfDxAndDyEdges, numberOfEdges,
           numberOfVertices;
 
-   VertexType origin, proportions;
+   PointType origin, proportions;
 
-   IndexType cellZNeighboursStep;
+   IndexType cellZNeighborsStep;
  
-   VertexType spaceSteps;
+   PointType spaceSteps;
  
    RealType spaceStepsProducts[ 5 ][ 5 ][ 5 ];
 
@@ -161,7 +164,7 @@ class Grid< 3, Real, Device, Index > : public Object
    friend class GridEntityGetter;
  
    template< typename, int, typename >
-   friend class NeighbourGridEntityGetter;
+   friend class NeighborGridEntityGetter;
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
index bf4cd4b891b8932eb2abe7935f4da699049a3bf9..b6cb533c3dc723a99163cc0b2b84dece2b9e3866 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
@@ -10,10 +10,14 @@
 
 #pragma once
 
+#include <fstream>
 #include <iomanip>
+#include <TNL/String.h>
 #include <TNL/Assert.h>
+#include <TNL/Logger.h>
+#include <TNL/Meshes/GridDetails/GnuplotWriter.h>
 #include <TNL/Meshes/GridDetails/GridEntityGetter_impl.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter3D_impl.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h>
 #include <TNL/Meshes/GridDetails/Grid3D.h>
 #include <TNL/Meshes/GridDetails/GridEntityMeasureGetter.h>
 
@@ -45,7 +49,7 @@ template< typename Real,
 String Grid< 3, Real, Device, Index > :: getType()
 {
    return String( "Meshes::Grid< " ) +
-          String( meshDimensions ) + ", " +
+          String( getMeshDimension() ) + ", " +
           String( TNL::getType< RealType >() ) + ", " +
           String( Device :: getDeviceType() ) + ", " +
           String( TNL::getType< IndexType >() ) + " >";
@@ -164,9 +168,9 @@ template< typename Real,
           typename Index >
 void Grid< 3, Real, Device, Index > :: setDimensions( const Index xSize, const Index ySize, const Index zSize )
 {
-   Assert( xSize > 0, std::cerr << "xSize = " << xSize );
-   Assert( ySize > 0, std::cerr << "ySize = " << ySize );
-   Assert( zSize > 0, std::cerr << "zSize = " << zSize );
+   TNL_ASSERT_GT( xSize, 0, "Grid size must be positive." );
+   TNL_ASSERT_GT( ySize, 0, "Grid size must be positive." );
+   TNL_ASSERT_GT( zSize, 0, "Grid size must be positive." );
 
    this->dimensions.x() = xSize;
    this->dimensions.y() = ySize;
@@ -188,7 +192,7 @@ void Grid< 3, Real, Device, Index > :: setDimensions( const Index xSize, const I
                          this->numberOfDzEdges;
    this->numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ) * ( zSize + 1 );
  
-   this->cellZNeighboursStep = xSize * ySize;
+   this->cellZNeighborsStep = xSize * ySize;
 
    computeSpaceSteps();
 }
@@ -214,8 +218,8 @@ const typename Grid< 3, Real, Device, Index > :: CoordinatesType&
 template< typename Real,
           typename Device,
           typename Index >
-void Grid< 3, Real, Device, Index > :: setDomain( const VertexType& origin,
-                                                     const VertexType& proportions )
+void Grid< 3, Real, Device, Index > :: setDomain( const PointType& origin,
+                                                     const PointType& proportions )
 {
    this->origin = origin;
    this->proportions = proportions;
@@ -226,7 +230,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename Grid< 3, Real, Device, Index >::VertexType&
+const typename Grid< 3, Real, Device, Index >::PointType&
 Grid< 3, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
@@ -236,25 +240,26 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename Grid< 3, Real, Device, Index > :: VertexType&
+const typename Grid< 3, Real, Device, Index > :: PointType&
    Grid< 3, Real, Device, Index > :: getProportions() const
 {
 	return this->proportions;
 }
 
+
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
+   template< int EntityDimension >
 __cuda_callable__  inline
 Index
 Grid< 3, Real, Device, Index >::
 getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 3 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityDimension <= 3 &&
+                  EntityDimension >= 0, "Wrong grid entity dimensions." );
  
-   switch( EntityType::entityDimensions )
+   switch( EntityDimension )
    {
       case 3:
          return this->numberOfCells;
@@ -271,84 +276,80 @@ getEntitiesCount() const
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
- __cuda_callable__ inline
-EntityType
+   template< typename Entity >
+__cuda_callable__  inline
+Index
 Grid< 3, Real, Device, Index >::
-getEntity( const IndexType& entityIndex ) const
+getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 3 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
- 
-   return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex );
+   return getEntitiesCount< Entity::getEntityDimension() >();
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
-__cuda_callable__ inline
-Index
+   template< typename Entity >
+ __cuda_callable__ inline
+Entity
 Grid< 3, Real, Device, Index >::
-getEntityIndex( const EntityType& entity ) const
+getEntity( const IndexType& entityIndex ) const
 {
-   static_assert( EntityType::entityDimensions <= 3 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( Entity::getEntityDimension() <= 3 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
  
-   return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
+   return GridEntityGetter< ThisType, Entity >::getEntity( *this, entityIndex );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< typename EntityType >
-__cuda_callable__
-Real
+   template< typename Entity >
+__cuda_callable__ inline
+Index
 Grid< 3, Real, Device, Index >::
-getEntityMeasure( const EntityType& entity ) const
+getEntityIndex( const Entity& entity ) const
 {
-   return GridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+   static_assert( Entity::getEntityDimension() <= 3 &&
+                  Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." );
+ 
+   return GridEntityGetter< ThisType, Entity >::getEntityIndex( *this, entity );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__
-const Real&
+__cuda_callable__ inline
+const typename Grid< 3, Real, Device, Index >::PointType&
 Grid< 3, Real, Device, Index >::
-getCellMeasure() const
+getSpaceSteps() const
 {
-   return this->template getSpaceStepsProducts< 1, 1, 1 >();
+   return this->spaceSteps;
 }
 
 template< typename Real,
           typename Device,
           typename Index >
+   template< int xPow, int yPow, int zPow >
 __cuda_callable__ inline
-typename Grid< 3, Real, Device, Index >::VertexType
+const Real&
 Grid< 3, Real, Device, Index >::
-getSpaceSteps() const
+getSpaceStepsProducts() const
 {
-   return this->spaceSteps;
+   static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" );
+   static_assert( yPow >= -2 && yPow <= 2, "unsupported value of yPow" );
+   static_assert( zPow >= -2 && zPow <= 2, "unsupported value of zPow" );
+   return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ][ zPow + 2 ];
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-   template< int xPow, int yPow, int zPow >
-__cuda_callable__ inline
+__cuda_callable__
 const Real&
 Grid< 3, Real, Device, Index >::
-getSpaceStepsProducts() const
+getCellMeasure() const
 {
-   Assert( xPow >= -2 && xPow <= 2,
-              std::cerr << " xPow = " << xPow );
-   Assert( yPow >= -2 && yPow <= 2,
-              std::cerr << " yPow = " << yPow );
-   Assert( zPow >= -2 && zPow <= 2,
-              std::cerr << " zPow = " << zPow );
-
-   return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ][ zPow + 2 ];
+   return this->template getSpaceStepsProducts< 1, 1, 1 >();
 }
 
 template< typename Real,
@@ -379,7 +380,7 @@ typename GridFunction::RealType
                                                  const typename GridFunction::RealType& p ) const
 {
    typename GridFunction::RealType lpNorm( 0.0 );
-   MeshEntity< getMeshDimensions() > cell;
+   Cell cell;
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
         cell.getCoordinates().z()++ )
@@ -407,7 +408,7 @@ template< typename Real,
                                                                            const GridFunction& f2 ) const
 {
    typename GridFunction::RealType maxDiff( -1.0 );
-   MeshEntity< getMeshDimensions() > cell( *this );
+   Cell cell( *this );
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
         cell.getCoordinates().z()++ )
@@ -434,8 +435,7 @@ template< typename Real,
                                                                  const typename GridFunction::RealType& p ) const
 {
    typename GridFunction::RealType lpNorm( 0.0 );
-   MeshEntity< getMeshDimensions() > cell( *this );
-
+   Cell cell( *this );
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
         cell.getCoordinates().z()++ )
@@ -511,7 +511,9 @@ template< typename Real,
 bool Grid< 3, Real, Device, Index >::writeMesh( const String& fileName,
                                                    const String& format ) const
 {
-   Assert( false, std::cerr << "TODO: FIX THIS"); // TODO: FIX THIS
+   /*****
+    * TODO: implement this
+    */
    return true;
 }
 
@@ -552,7 +554,7 @@ bool Grid< 3, Real, Device, Index > :: write( const MeshFunction& function,
                  cell.getCoordinates().x() < getDimensions().x();
                  cell.getCoordinates().x()++ )
             {
-               VertexType v = cell.getCenter();
+               PointType v = cell.getCenter();
                GnuplotWriter::write( file, v );
                GnuplotWriter::write( file, function[ this->template getEntityIndex( cell ) ] );
                file << std::endl;
@@ -573,11 +575,14 @@ void
 Grid< 3, Real, Device, Index >::
 writeProlog( Logger& logger )
 {
-   logger.writeParameter( "Dimensions:", getMeshDimensions() );
+   logger.writeParameter( "Dimension:", getMeshDimension() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
    logger.writeParameter( "Space steps:", this->getSpaceSteps() );
+   logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() );
+   logger.writeParameter( "Number of faces:", getEntitiesCount< Face >() );
+   logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() );
 }
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h b/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h
index 0f58430dd84e23f78492cc279ab24f571ccce9bb..853b7810feaca9076d183b37bb44a76e79e2c18f 100644
--- a/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h
+++ b/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h
@@ -32,13 +32,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >
  
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 1, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x() );
       }
 };
@@ -53,13 +53,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >
  
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 0, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + ( entity.getCoordinates().x() ) * grid.getSpaceSteps().x() );
       }
 };
@@ -77,13 +77,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 2, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x(),
             grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 ) * grid.getSpaceSteps().y() );
       }
@@ -99,13 +99,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 1, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() +
                ( entity.getCoordinates().x() + 0.5 * entity.getBasis().x() ) * grid.getSpaceSteps().x(),
             grid.getOrigin().y() +
@@ -124,13 +124,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 0, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + entity.getCoordinates().x() * grid.getSpaceSteps().x(),
             grid.getOrigin().y() + entity.getCoordinates().y() * grid.getSpaceSteps().y() );
       }
@@ -143,21 +143,21 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >
 template< typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
-class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, EntityDimensions, Config > >
+class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, EntityDimension, Config > >
 {
    public:
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() +
                ( entity.getCoordinates().x() + 0.5 * entity.getBasis().x() ) * grid.getSpaceSteps().x(),
             grid.getOrigin().y() +
@@ -177,13 +177,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 3, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x(),
             grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 ) * grid.getSpaceSteps().y(),
             grid.getOrigin().z() + ( entity.getCoordinates().z() + 0.5 ) * grid.getSpaceSteps().z() );
@@ -200,13 +200,13 @@ class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef GridEntity< GridType, 0, Config > GridEntityType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
  
       __cuda_callable__ inline
-      static VertexType getEntityCenter( const GridEntityType& entity )
+      static PointType getEntityCenter( const GridEntityType& entity )
       {
          const GridType& grid = entity.getMesh();
-         return VertexType(
+         return PointType(
             grid.getOrigin().x() + ( entity.getCoordinates().x() ) * grid.getSpaceSteps().x(),
             grid.getOrigin().y() + ( entity.getCoordinates().y() ) * grid.getSpaceSteps().y(),
             grid.getOrigin().z() + ( entity.getCoordinates().z() ) * grid.getSpaceSteps().z() );
diff --git a/src/TNL/Meshes/GridDetails/GridEntityGetter.h b/src/TNL/Meshes/GridDetails/GridEntityGetter.h
index 1467e99476e310cc56c47c84123f87c638010c0b..1c092e41be541a66b30cb330a8ef6689cdcaf717 100644
--- a/src/TNL/Meshes/GridDetails/GridEntityGetter.h
+++ b/src/TNL/Meshes/GridDetails/GridEntityGetter.h
@@ -15,7 +15,7 @@ namespace Meshes {
 
 template< typename Grid,
           typename GridEntity,
-          int EntityDimensions = GridEntity::entityDimensions >
+          int EntityDimension = GridEntity::getEntityDimension() >
 class GridEntityGetter
 {
    //static_assert( false, "Wrong mesh type or entity topology." );
diff --git a/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h b/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h
index e3f93e4599e6b1e30a46e25d1afdd2280b7ef00e..49bc86956d659edff903b15927a1f4753c80fab2 100644
--- a/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h
+++ b/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h
@@ -25,45 +25,40 @@ template< typename Real,
           typename Device,
           typename Index,
           typename GridEntity,
-          int EntityDimensions >
+          int EntityDimension >
 class GridEntityGetter<
    Meshes::Grid< 1, Real, Device, Index >,
    GridEntity,
-   EntityDimensions >
+   EntityDimension >
 {
    public:
  
-      static const int entityDimensions = EntityDimensions;
+      static const int entityDimension = EntityDimension;
  
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-              std::cerr << " index = " << index
-                   << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                   << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
          return GridEntity
             ( grid,
               CoordinatesType( index ),
               typename GridEntity::EntityOrientationType( 0 ),
-              typename GridEntity::EntityBasisType( EntityDimensions ) );
+              typename GridEntity::EntityBasisType( EntityDimension ) );
       }
  
       __cuda_callable__ inline
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions() + CoordinatesType( 1 - entityDimensions ),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " grid.getDimensions() = " << grid.getDimensions()
-                   << " EntityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions() + CoordinatesType( 1 - entityDimension ), "wrong coordinates" );
          return entity.getCoordinates().x();
       }
 };
@@ -79,21 +74,19 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >
 {
    public:
  
-      static const int entityDimensions = 2;
+      static const int entityDimension = 2;
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
 
          const CoordinatesType dimensions = grid.getDimensions();
 
@@ -109,10 +102,8 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " grid.getDimensions() = " << grid.getDimensions() );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" );
 
          //const CoordinatesType coordinates = entity.getCoordinates();
          //const CoordinatesType dimensions = grid.getDimensions();
@@ -131,21 +122,19 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >
 {
    public:
  
-      static const int entityDimensions = 1;
+      static const int entityDimension = 1;
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions, EntityConfig > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension, EntityConfig > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
  
          const CoordinatesType dimensions = grid.getDimensions();
 
@@ -171,11 +160,8 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions() + abs( entity.getOrientation() ),
-                 std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                      << " dimensions.x() = " << grid.getDimensions()
-                      << " abs( entity.getOrientation() ) = " << abs( entity.getOrientation() ) );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions() + abs( entity.getOrientation() ), "wrong coordinates" );
  
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -194,21 +180,19 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >
 {
    public:
  
-      static const int entityDimensions = 0;
+      static const int entityDimension = 0;
  
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
 
          const CoordinatesType dimensions = grid.getDimensions();
 
@@ -225,9 +209,8 @@ class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= 0 && entity.getCoordinates() <= grid.getDimensions(),
-            std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                 << " grid.getDimensions() = " << grid.getDimensions() );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" );
  
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -247,21 +230,19 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >
 {
    public:
  
-      static const int entityDimensions = 3;
+      static const int entityDimension = 3;
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
 
          const CoordinatesType dimensions = grid.getDimensions();
 
@@ -278,10 +259,8 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " grid.getDimensions() = " << grid.getDimensions() );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" );
 
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -299,21 +278,19 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >
 {
    public:
  
-      static const int entityDimensions = 2;
+      static const int entityDimension = 2;
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
 
          const CoordinatesType dimensions = grid.getDimensions();
  
@@ -354,11 +331,8 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions() + abs( entity.getOrientation() ),
-                 std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                      << " dimensions.x() = " << grid.getDimensions()
-                      << " abs( entity.getOrientation() ) = " << abs( entity.getOrientation() ) );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions() + abs( entity.getOrientation() ), "wrong coordinates" );
  
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -389,21 +363,19 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >
 {
    public:
  
-      static const int entityDimensions = 1;
+      static const int entityDimension = 1;
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
  
          const CoordinatesType dimensions = grid.getDimensions();
 
@@ -447,12 +419,10 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < grid.getDimensions() +
-                       CoordinatesType( 1, 1, 1 ) - entity.getBasis(),
-            std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                 << " dimensions.x() = " << grid.getDimensions()
-                 << " CoordinatesType( 1, 1, 1 ) - entity.getBasis() = " << CoordinatesType( 1, 1, 1 ) - entity.getBasis() );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(),
+                        grid.getDimensions() + CoordinatesType( 1, 1, 1 ) - entity.getBasis(),
+                        "wrong coordinates" );
  
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -479,21 +449,19 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >
 {
    public:
  
-      static const int entityDimensions = 0;
+      static const int entityDimension = 0;
  
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      //typedef typename GridType::template GridEntity< entityDimensions > GridEntity;
+      //typedef typename GridType::template GridEntity< entityDimension > GridEntity;
  
       __cuda_callable__ inline
       static GridEntity getEntity( const GridType& grid,
                                    const IndexType& index )
       {
-         Assert( index >= 0 && index < grid.template getEntitiesCount< GridEntity >(),
-           std::cerr << " index = " << index
-                << " grid.getEntitiesCount<>() = " << grid.template getEntitiesCount< GridEntity >()
-                << " entityDimensions = " << entityDimensions );
+         TNL_ASSERT_GE( index, 0, "Index must be non-negative." );
+         TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." );
 
          const CoordinatesType dimensions = grid.getDimensions();
  
@@ -512,9 +480,8 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >
       static IndexType getEntityIndex( const GridType& grid,
                                        const GridEntity& entity )
       {
-         Assert( entity.getCoordinates() >= 0 && entity.getCoordinates() <= grid.getDimensions(),
-            std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                 << " grid.getDimensions() = " << grid.getDimensions() );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" );
  
          const CoordinatesType coordinates = entity.getCoordinates();
          const CoordinatesType dimensions = grid.getDimensions();
@@ -527,4 +494,3 @@ class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >
 
 } // namespace Meshes
 } // namespace TNL
-
diff --git a/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h b/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h
index 0bf847c3e83c3d36e741f1b974eb4da4d3c36b6a..a9823bf6c4e8b84d0daf0991f1ed87a722d12cfc 100644
--- a/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h
+++ b/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h
@@ -14,7 +14,7 @@ namespace TNL {
 namespace Meshes {
 
 template< typename Grid,
-          int EntityDimensions >
+          int EntityDimension >
 class GridEntityMeasureGetter
 {
 };
@@ -22,15 +22,15 @@ class GridEntityMeasureGetter
 /***
  * Common implementation for vertices
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index >
-class GridEntityMeasureGetter< Meshes::Grid< Dimensions, Real, Device, Index >, 0 >
+class GridEntityMeasureGetter< Meshes::Grid< Dimension, Real, Device, Index >, 0 >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
  
       template< typename EntityType >
       __cuda_callable__ inline
diff --git a/src/TNL/Meshes/GridDetails/GridEntityTopology.h b/src/TNL/Meshes/GridDetails/GridEntityTopology.h
index 7d0bf23049d219b924ec24bdcdb529a705fbc6c2..9a9ba9e317c23926ce171063162686c8c57e954d 100644
--- a/src/TNL/Meshes/GridDetails/GridEntityTopology.h
+++ b/src/TNL/Meshes/GridDetails/GridEntityTopology.h
@@ -15,7 +15,7 @@ namespace Meshes {
 
 
 template< typename Grid,
-          int EntityDimensions,
+          int EntityDimension,
           typename EntityOrientation_,
           typename EntityProportions_ >
 class GridEntityTopology
@@ -25,17 +25,17 @@ class GridEntityTopology
       typedef Grid GridType;
  
       // TODO: restore when CUDA allows it
-      //static const int meshDimensions = GridType::Dimensions;
-      enum { meshDimensions = GridType::Dimensions };
+      //static const int meshDimension = GridType::getMeshDimension();
+      enum { meshDimension = GridType::getMeshDimension() };
  
-      static const int entityDimensions = EntityDimensions;
+      static const int entityDimension = EntityDimension;
  
       typedef EntityOrientation_ EntityOrientation;
  
       typedef EntityProportions_ EntityProportions;
  
       // TODO: restore when CUDA allows it
-   //static_assert( meshDimensions == EntityOrientation_::size,
+   //static_assert( meshDimension == EntityOrientation_::size,
    //               "Entity orientation is not a proper static multiindex." );
 };
 
diff --git a/src/TNL/Meshes/GridDetails/GridEntity_impl.h b/src/TNL/Meshes/GridDetails/GridEntity_impl.h
index 6510e2ab2102d59c3ca9816e1bb8ad222a081e23..8703c064fd6e2271ea3705ddb4355261edf14cd9 100644
--- a/src/TNL/Meshes/GridDetails/GridEntity_impl.h
+++ b/src/TNL/Meshes/GridDetails/GridEntity_impl.h
@@ -19,44 +19,44 @@
 namespace TNL {
 namespace Meshes {
 
-/*template< int Dimensions,
+/*template< int Dimension,
           typename Real,
           typename Device,
           typename Index,          typename Config,
-          int EntityDimensions >
+          int EntityDimension >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension >::
 GridEntity()
 {
 }*/
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
-GridEntity( const Meshes::Grid< Dimensions, Real, Device, Index >& grid )
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
+GridEntity( const Meshes::Grid< Dimension, Real, Device, Index >& grid )
 : grid( grid ),
   entityIndex( -1 ),
   coordinates( 0 ),
   orientation( 0 ),
   basis( 0 ),
-  neighbourEntitiesStorage( *this )
+  neighborEntitiesStorage( *this )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
-GridEntity( const Meshes::Grid< Dimensions, Real, Device, Index >& grid,
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
+GridEntity( const Meshes::Grid< Dimension, Real, Device, Index >& grid,
                const CoordinatesType& coordinates,
                const EntityOrientationType& orientation,
                const EntityBasisType& basis )
@@ -65,214 +65,212 @@ GridEntity( const Meshes::Grid< Dimensions, Real, Device, Index >& grid,
   coordinates( coordinates ),
   orientation( orientation ),
   basis( basis ),
-  neighbourEntitiesStorage( *this )
+  neighborEntitiesStorage( *this )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getCoordinates() const
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getCoordinates()
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 setCoordinates( const CoordinatesType& coordinates )
 {
    this->coordinates = coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 refresh()
 {
    this->entityIndex = this->grid.getEntityIndex( *this );
-   this->neighbourEntitiesStorage.refresh( this->grid, this->entityIndex );
+   this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 Index
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getIndex() const
 {
-   typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
-   typedef typename GridType::template MeshEntity< EntityDimensions > EntityType;
-   Assert( this->entityIndex >= 0 &&
-              this-> entityIndex < grid.template getEntitiesCount< EntityType >(),
-              std::cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.template getEntitiesCount< EntityDimensions >() = " << grid.template getEntitiesCount< EntityType >() );
-   Assert( this->entityIndex == grid.getEntityIndex( *this ),
-              std::cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.getEntityIndex( *this ) = " << grid.getEntityIndex( *this ) );
+   typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
+   typedef typename GridType::template EntityType< EntityDimension > EntityType;
+   TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." );
+   TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< EntityDimension >(),
+                  "Entity index is out of bounds." );
+   TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ),
+                  "Wrong value of stored index." );
    return this->entityIndex;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::EntityOrientationType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::EntityOrientationType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getOrientation() const
 {
    return this->orientation;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 setOrientation( const EntityOrientationType& orientation )
 {
    this->orientation = orientation;
    this->basis = EntityBasisType( 1 ) - abs( orientation );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::EntityBasisType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::EntityBasisType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getBasis() const
 {
    return this->basis;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 setBasis( const EntityBasisType& basis )
 {
    this->basis = basis;
    this->orientation = EntityOrientationType( 1 ) - abs( basis );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
-   template< int NeighbourEntityDimensions >
+   template< int NeighborEntityDimension >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::template NeighbourEntities< NeighbourEntityDimensions >&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
-getNeighbourEntities() const
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::template NeighborEntities< NeighborEntityDimension >&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
+getNeighborEntities() const
 {
-   return neighbourEntitiesStorage.template getNeighbourEntities< NeighbourEntityDimensions >();
+   return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >();
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
 bool
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 isBoundaryEntity() const
 {
    return BoundaryGridEntityChecker< ThisType >::isBoundaryEntity( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-typename Meshes::Grid< Dimensions, Real, Device, Index >::VertexType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+typename Meshes::Grid< Dimension, Real, Device, Index >::PointType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getCenter() const
 {
    return GridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::RealType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::RealType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getMeasure() const
 {
-   return GridEntityMeasureGetter< GridType, EntityDimensions >::getMeasure( this->getMesh(), *this );
+   return GridEntityMeasureGetter< GridType, EntityDimension >::getMeasure( this->getMesh(), *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::GridType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::GridType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::
 getMesh() const
 {
    return this->grid;
@@ -281,38 +279,38 @@ getMesh() const
 /****
  * Specialization for cells
  */
-/*template< int Dimensions,
+/*template< int Dimension,
           typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension >::
 GridEntity()
 {
 }*/
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 GridEntity( const GridType& grid )
 : grid( grid ),
   entityIndex( -1 ),
-  neighbourEntitiesStorage( *this )
+  neighborEntitiesStorage( *this )
 {
    this->coordinates = CoordinatesType( ( Index ) 0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 GridEntity( const GridType& grid,
                const CoordinatesType& coordinates,
                const EntityOrientationType& orientation,
@@ -320,184 +318,182 @@ GridEntity( const GridType& grid,
 : grid( grid ),
   entityIndex( -1 ),
   coordinates( coordinates ),
-  neighbourEntitiesStorage( *this )
+  neighborEntitiesStorage( *this )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getCoordinates() const
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getCoordinates()
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 setCoordinates( const CoordinatesType& coordinates )
 {
    this->coordinates = coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 refresh()
 {
    this->entityIndex = this->grid.getEntityIndex( *this );
-   this->neighbourEntitiesStorage.refresh( this->grid, this->entityIndex );
+   this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 Index
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getIndex() const
 {
-   Assert( this->entityIndex >= 0 &&
-              this-> entityIndex < grid.template getEntitiesCount< ThisType >(),
-              std::cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.template getEntitiesCount< Dimensions >() = " << grid.template getEntitiesCount< ThisType >() );
-   Assert( this->entityIndex == grid.getEntityIndex( *this ),
-              std::cerr << "this->index = " << this->entityIndex
-                   << " grid.getEntityIndex( *this ) = " << grid.getEntityIndex( *this ) );
+   TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." );
+   TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< Dimension >(),
+                  "Entity index is out of bounds." );
+   TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ),
+                  "Wrong value of stored index." );
    return this->entityIndex;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::EntityOrientationType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::EntityOrientationType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getOrientation() const
 {
    return EntityOrientationType( ( IndexType ) 0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::EntityBasisType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::EntityBasisType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getBasis() const
 {
    return EntityBasisType( ( IndexType ) 1 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
-   template< int NeighbourEntityDimensions >
+   template< int NeighborEntityDimension >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::template NeighbourEntities< NeighbourEntityDimensions >&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
-getNeighbourEntities() const
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::template NeighborEntities< NeighborEntityDimension >&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
+getNeighborEntities() const
 {
-   return neighbourEntitiesStorage.template getNeighbourEntities< NeighbourEntityDimensions >();
+   return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >();
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 bool
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 isBoundaryEntity() const
 {
    return BoundaryGridEntityChecker< ThisType >::isBoundaryEntity( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-typename Meshes::Grid< Dimensions, Real, Device, Index >::VertexType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+typename Meshes::Grid< Dimension, Real, Device, Index >::PointType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getCenter() const
 {
    return GridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::RealType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::RealType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getMeasure() const
 {
    return this->getMesh().getCellMeasure();
 }
 
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::VertexType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::PointType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getEntityProportions() const
 {
    return grid.getSpaceSteps();
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::GridType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::GridType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::
 getMesh() const
 {
    return this->grid;
@@ -507,28 +503,28 @@ getMesh() const
 /****
  * Specialization for vertices
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 GridEntity( const GridType& grid )
  : grid( grid ),
    entityIndex( -1 ),
    coordinates( 0 ),
-   neighbourEntitiesStorage( *this )
+   neighborEntitiesStorage( *this )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 GridEntity( const GridType& grid,
                const CoordinatesType& coordinates,
                const EntityOrientationType& orientation,
@@ -536,186 +532,184 @@ GridEntity( const GridType& grid,
 : grid( grid ),
   entityIndex( -1 ),
   coordinates( coordinates ),
-  neighbourEntitiesStorage( *this )
+  neighborEntitiesStorage( *this )
 {
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getCoordinates() const
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::CoordinatesType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::CoordinatesType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getCoordinates()
 {
    return this->coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 setCoordinates( const CoordinatesType& coordinates )
 {
    this->coordinates = coordinates;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 void
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 refresh()
 {
    this->entityIndex = this->grid.getEntityIndex( *this );
-   this->neighbourEntitiesStorage.refresh( this->grid, this->entityIndex );
+   this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 Index
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getIndex() const
 {
-   typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+   typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
    typedef typename GridType::Vertex Vertex;
-   Assert( this->entityIndex >= 0 &&
-              this-> entityIndex < grid.template getEntitiesCount< Vertex >(),
-              std::cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.template getEntitiesCount< 0 >() = " << grid.template getEntitiesCount< Vertex >() );
-   Assert( this->entityIndex == grid.getEntityIndex( *this ),
-              std::cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.getEntityIndex( *this ) = " << grid.getEntityIndex( *this ) );
+   TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." );
+   TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< 0 >(),
+                  "Entity index is out of bounds." );
+   TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ),
+                  "Wrong value of stored index." );
    return this->entityIndex;
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::EntityOrientationType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::EntityOrientationType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getOrientation() const
 {
    return EntityOrientationType( ( IndexType ) 0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::EntityBasisType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::EntityBasisType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getBasis() const
 {
    return EntityBasisType( ( IndexType ) 0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
-   template< int NeighbourEntityDimensions >
+   template< int NeighborEntityDimension >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::template NeighbourEntities< NeighbourEntityDimensions >&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
-getNeighbourEntities() const
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::template NeighborEntities< NeighborEntityDimension >&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
+getNeighborEntities() const
 {
-   return neighbourEntitiesStorage.template getNeighbourEntities< NeighbourEntityDimensions >();
+   return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >();
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
 bool
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 isBoundaryEntity() const
 {
    return BoundaryGridEntityChecker< ThisType >::isBoundaryEntity( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-typename Meshes::Grid< Dimensions, Real, Device, Index >::VertexType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+typename Meshes::Grid< Dimension, Real, Device, Index >::PointType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getCenter() const
 {
    return GridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::RealType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::RealType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getMeasure() const
 {
    return 0.0;
 }
 
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::VertexType
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::PointType
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getEntityProportions() const
 {
-   return VertexType( 0.0 );
+   return PointType( 0.0 );
 }
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
 __cuda_callable__ inline
-const typename GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::GridType&
-GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >::
+const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::GridType&
+GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::
 getMesh() const
 {
    return this->grid;
diff --git a/src/TNL/Meshes/GridDetails/GridTraverser.h b/src/TNL/Meshes/GridDetails/GridTraverser.h
index 8365f41d7944e04291f13a849afb57832cbc2274..7e821d714bcdb3b6081ac59ae160ab898434979b 100644
--- a/src/TNL/Meshes/GridDetails/GridTraverser.h
+++ b/src/TNL/Meshes/GridDetails/GridTraverser.h
@@ -85,6 +85,38 @@ class GridTraverser< Meshes::Grid< 1, Real, Devices::Cuda, Index > >
          const int& stream = 0 );
 };
 
+/****
+ * 1D grid, Devices::MIC
+ */
+template< typename Real,
+          typename Index >
+class GridTraverser< Meshes::Grid< 1, Real, Devices::MIC, Index > >
+{
+   public:
+      
+      typedef Meshes::Grid< 1, Real, Devices::MIC, Index > GridType;
+      typedef SharedPointer< GridType > GridPointer;
+      typedef Real RealType;
+      typedef Devices::MIC DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+ 
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities  >
+      static void
+      processEntities(
+         const GridPointer& gridPointer,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         SharedPointer< UserData, DeviceType >& userData,
+         const int& stream = 0 );
+};
+
+
+
 /****
  * 2D grid, Devices::Host
  */
@@ -161,6 +193,44 @@ class GridTraverser< Meshes::Grid< 2, Real, Devices::Cuda, Index > >
          const GridEntityParameters&... gridEntityParameters );
 };
 
+/****
+ * 2D grid, Devices::MIC
+ */
+template< typename Real,
+          typename Index >
+class GridTraverser< Meshes::Grid< 2, Real, Devices::MIC, Index > >
+{
+   public:
+      
+      typedef Meshes::Grid< 2, Real, Devices::MIC, Index > GridType;
+      typedef SharedPointer< GridType > GridPointer;
+      typedef Real RealType;
+      typedef Devices::MIC DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+ 
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1,
+         typename... GridEntityParameters >
+      static void
+      processEntities(
+         const GridPointer& gridPointer,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         SharedPointer< UserData, DeviceType >& userData,
+         // FIXME: hack around nvcc bug (error: default argument not at end of parameter list)
+//         const int& stream = 0,
+         const int& stream,
+         // gridEntityParameters are passed to GridEntity's constructor
+         // (i.e. orientation and basis for faces)
+         const GridEntityParameters&... gridEntityParameters );
+};
+
 /****
  * 3D grid, Devices::Host
  */
@@ -239,6 +309,45 @@ class GridTraverser< Meshes::Grid< 3, Real, Devices::Cuda, Index > >
          const GridEntityParameters&... gridEntityParameters );
 };
 
+/****
+ * 3D grid, Devices::Cuda
+ */
+template< typename Real,
+          typename Index >
+class GridTraverser< Meshes::Grid< 3, Real, Devices::MIC, Index > >
+{
+   public:
+      
+      typedef Meshes::Grid< 3, Real, Devices::MIC, Index > GridType;
+      typedef SharedPointer< GridType > GridPointer;
+      typedef Real RealType;
+      typedef Devices::MIC DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+ 
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1,
+         int ZOrthogonalBoundary = 1,
+         typename... GridEntityParameters >
+      static void
+      processEntities(
+         const GridPointer& gridPointer,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         SharedPointer< UserData, DeviceType >& userData,
+         // FIXME: hack around nvcc bug (error: default argument not at end of parameter list)
+//         const int& stream = 0,
+         const int& stream,
+         // gridEntityParameters are passed to GridEntity's constructor
+         // (i.e. orientation and basis for faces and edges)
+         const GridEntityParameters&... gridEntityParameters );
+};
+
 } // namespace Meshes
 } // namespace TNL
 
diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_impl.h b/src/TNL/Meshes/GridDetails/GridTraverser_impl.h
index 458069ce5d1c9af6f00f519d5e3c0044fa544fee..4443e161c3d3296f7a7924d927f00a3581248cec 100644
--- a/src/TNL/Meshes/GridDetails/GridTraverser_impl.h
+++ b/src/TNL/Meshes/GridDetails/GridTraverser_impl.h
@@ -8,8 +8,14 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+#include <TNL/Devices/MIC.h>
+
 #pragma once
 
+#include "GridTraverser.h"
+
+#include <TNL/Exceptions/CudaSupportMissing.h>
+
 namespace TNL {
 namespace Meshes {
 
@@ -193,11 +199,75 @@ processEntities(
    if( stream == 0 )
    {
       cudaStreamSynchronize( s );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
    }
+#else
+   throw Exceptions::CudaSupportMissing();
 #endif
 }
 
+/****
+ * 1D traverser, MIC
+ */
+
+template< typename Real,
+          typename Index >
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities >
+void
+GridTraverser< Meshes::Grid< 1, Real, Devices::MIC, Index > >::
+processEntities(
+   const GridPointer& gridPointer,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   SharedPointer< UserData, DeviceType >& userDataPointer,
+   const int& stream )
+{
+    std::cout << "Not Implemented yet Grid Traverser <1, Real, Device::MIC>" << std::endl;
+/*
+   auto& pool = CudaStreamPool::getInstance();
+   const cudaStream_t& s = pool.getStream( stream );
+
+   Devices::Cuda::synchronizeDevice();
+   if( processOnlyBoundaryEntities )
+   {
+      dim3 cudaBlockSize( 2 );
+      dim3 cudaBlocks( 1 );
+      GridBoundaryTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor >
+            <<< cudaBlocks, cudaBlockSize, 0, s >>>
+            ( &gridPointer.template getData< Devices::Cuda >(),
+              &userDataPointer.template modifyData< Devices::Cuda >(),
+              begin,
+              end );
+   }
+   else
+   {
+      dim3 cudaBlockSize( 256 );
+      dim3 cudaBlocks;
+      cudaBlocks.x = Devices::Cuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
+      const IndexType cudaXGrids = Devices::Cuda::getNumberOfGrids( cudaBlocks.x );
+
+      for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
+         GridTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor >
+            <<< cudaBlocks, cudaBlockSize, 0, s >>>
+            ( &gridPointer.template getData< Devices::Cuda >(),
+              &userDataPointer.template modifyData< Devices::Cuda >(),
+              begin,
+              end,
+              gridXIdx );
+   }
+
+   // only launches into the stream 0 are synchronized
+   if( stream == 0 )
+   {
+      cudaStreamSynchronize( s );
+      checkCudaDevice;
+   }
+*/
+}
 
 /****
  * 2D traverser, host
@@ -302,16 +372,32 @@ GridTraverser2D(
    UserData* userData,
    const typename GridEntity::CoordinatesType begin,
    const typename GridEntity::CoordinatesType end,
-   const Index gridXIdx,
-   const Index gridYIdx,
+   const dim3 gridIdx,
    const GridEntityParameters... gridEntityParameters )
 {
    typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType;
    typename GridType::CoordinatesType coordinates;
 
-   coordinates.x() = begin.x() + ( gridXIdx * Devices::Cuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = begin.y() + ( gridYIdx * Devices::Cuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;  
-
+   coordinates.x() = begin.x() + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.y() = begin.y() + Devices::Cuda::getGlobalThreadIdx_y( gridIdx );
+   
+   /*if( processOnlyBoundaryEntities && 
+      ( GridEntity::getMeshDimension() == 2 || GridEntity::getMeshDimension() == 0 ) )
+   {
+      if( coordinates.x() == begin.x() || coordinates.x() == end.x() ||
+          coordinates.y() == begin.y() || coordinates.y() == end.y() )
+      {
+         GridEntity entity( *grid, coordinates, gridEntityParameters... );
+         entity.refresh();
+         EntitiesProcessor::processEntity
+         ( *grid,
+           *userData,
+           entity );
+      }
+      return;
+   }*/
+   
+   
    if( coordinates <= end )
    {
       GridEntity entity( *grid, coordinates, gridEntityParameters... );
@@ -319,12 +405,81 @@ GridTraverser2D(
       if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
       {
          EntitiesProcessor::processEntity
-         ( entity.getMesh(),
+         ( *grid,
            *userData,
            entity );
       }
    }
 }
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities,
+          typename... GridEntityParameters >
+__global__ void 
+GridTraverser2DBoundaryAlongX(
+   const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid,
+   UserData* userData,
+   const Index beginX,
+   const Index endX,
+   const Index fixedY,
+   const dim3 gridIdx,
+   const GridEntityParameters... gridEntityParameters )
+{
+   typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = beginX + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.y() = fixedY;  
+   
+   if( coordinates.x() <= endX )
+   {
+      GridEntity entity( *grid, coordinates, gridEntityParameters... );
+      entity.refresh();
+      EntitiesProcessor::processEntity
+      ( *grid,
+        *userData,
+        entity );
+   }   
+}
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities,
+          typename... GridEntityParameters >
+__global__ void 
+GridTraverser2DBoundaryAlongY(
+   const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid,
+   UserData* userData,
+   const Index beginY,
+   const Index endY,
+   const Index fixedX,
+   const dim3 gridIdx,
+   const GridEntityParameters... gridEntityParameters )
+{
+   typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = fixedX;
+   coordinates.y() = beginY + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   
+   if( coordinates.y() <= endY )
+   {
+      GridEntity entity( *grid, coordinates, gridEntityParameters... );
+      entity.refresh();
+      EntitiesProcessor::processEntity
+      ( *grid,
+        *userData,
+        entity );
+   }   
+}
+
 #endif
 
 template< typename Real,
@@ -347,36 +502,210 @@ processEntities(
    const int& stream,
    const GridEntityParameters&... gridEntityParameters )
 {
-#ifdef HAVE_CUDA   
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = Devices::Cuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = Devices::Cuda::getNumberOfBlocks( end.y() - begin.y() + 1, cudaBlockSize.y );
-   const IndexType cudaXGrids = Devices::Cuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = Devices::Cuda::getNumberOfGrids( cudaBlocks.y );
+#ifdef HAVE_CUDA
+   if( processOnlyBoundaryEntities && 
+      ( GridEntity::getMeshDimension() == 2 || GridEntity::getMeshDimension() == 0 ) )
+   {
+      dim3 cudaBlockSize( 256 );
+      dim3 cudaBlocksCountAlongX, cudaGridsCountAlongX,
+           cudaBlocksCountAlongY, cudaGridsCountAlongY;
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongX, cudaGridsCountAlongX, end.x() - begin.x() + 1 );
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongY, cudaGridsCountAlongY, end.y() - begin.y() - 1 );
+            
+      auto& pool = CudaStreamPool::getInstance();
+      Devices::Cuda::synchronizeDevice();
+      
+      const cudaStream_t& s1 = pool.getStream( stream );
+      const cudaStream_t& s2 = pool.getStream( stream + 1 );
+      dim3 gridIdx, cudaGridSize;
+      for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongX.x; gridIdx.x++ )
+      {
+         Devices::Cuda::setupGrid( cudaBlocksCountAlongX, cudaGridsCountAlongX, gridIdx, cudaGridSize );
+         //Devices::Cuda::printThreadsSetup( cudaBlockSize, cudaBlocksCountAlongX, cudaGridSize, cudaGridsCountAlongX );
+         GridTraverser2DBoundaryAlongX< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+               <<< cudaGridSize, cudaBlockSize, 0, s1 >>>
+               ( &gridPointer.template getData< Devices::Cuda >(),
+                 &userDataPointer.template modifyData< Devices::Cuda >(),
+                 begin.x(),
+                 end.x(),
+                 begin.y(),
+                 gridIdx,
+                 gridEntityParameters... );
+         GridTraverser2DBoundaryAlongX< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+               <<< cudaGridSize, cudaBlockSize, 0, s2 >>>
+               ( &gridPointer.template getData< Devices::Cuda >(),
+                 &userDataPointer.template modifyData< Devices::Cuda >(),
+                 begin.x(),
+                 end.x(),
+                 end.y(),
+                 gridIdx,
+                 gridEntityParameters... );
+      }
+      const cudaStream_t& s3 = pool.getStream( stream + 2 );
+      const cudaStream_t& s4 = pool.getStream( stream + 3 );
+      for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongY.x; gridIdx.x++ )
+      {
+         Devices::Cuda::setupGrid( cudaBlocksCountAlongY, cudaGridsCountAlongY, gridIdx, cudaGridSize );
+         GridTraverser2DBoundaryAlongY< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+               <<< cudaGridSize, cudaBlockSize, 0, s3 >>>
+               ( &gridPointer.template getData< Devices::Cuda >(),
+                 &userDataPointer.template modifyData< Devices::Cuda >(),
+                 begin.y() + 1,
+                 end.y() - 1,
+                 begin.x(),
+                 gridIdx,
+                 gridEntityParameters... );
+         GridTraverser2DBoundaryAlongY< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+               <<< cudaGridSize, cudaBlockSize, 0, s4 >>>
+               ( &gridPointer.template getData< Devices::Cuda >(),
+                 &userDataPointer.template modifyData< Devices::Cuda >(),
+                 begin.y() + 1,
+                 end.y() - 1,
+                 end.x(),
+                 gridIdx,
+                 gridEntityParameters... );
+      }
+      cudaStreamSynchronize( s1 );
+      cudaStreamSynchronize( s2 );
+      cudaStreamSynchronize( s3 );
+      cudaStreamSynchronize( s4 );
+      TNL_CHECK_CUDA_DEVICE;
+   }
+   else
+   {
+      dim3 cudaBlockSize( 16, 16 );
+      dim3 cudaBlocksCount, cudaGridsCount;
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCount, cudaGridsCount,
+                                   end.x() - begin.x() + 1,
+                                   end.y() - begin.y() + 1 );
+      
+      auto& pool = CudaStreamPool::getInstance();
+      const cudaStream_t& s = pool.getStream( stream );
 
-   auto& pool = CudaStreamPool::getInstance();
-   const cudaStream_t& s = pool.getStream( stream );
+      Devices::Cuda::synchronizeDevice();
+      dim3 gridIdx, cudaGridSize;
+      for( gridIdx.y = 0; gridIdx.y < cudaGridsCount.y; gridIdx.y ++ )
+         for( gridIdx.x = 0; gridIdx.x < cudaGridsCount.x; gridIdx.x ++ )
+         {
+            Devices::Cuda::setupGrid( cudaBlocksCount, cudaGridsCount, gridIdx, cudaGridSize );
+	    //Devices::Cuda::printThreadsSetup( cudaBlockSize, cudaBlocksCount, cudaGridSize, cudaGridsCount );
+            GridTraverser2D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+               <<< cudaGridSize, cudaBlockSize, 0, s >>>
+               ( &gridPointer.template getData< Devices::Cuda >(),
+                 &userDataPointer.template modifyData< Devices::Cuda >(),
+                 begin,
+                 end,
+                 gridIdx,
+                 gridEntityParameters... );
+         }
 
-   Devices::Cuda::synchronizeDevice();
-   for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-         GridTraverser2D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
-            <<< cudaBlocks, cudaBlockSize, 0, s >>>
-            ( &gridPointer.template getData< Devices::Cuda >(),
-              &userDataPointer.template modifyData< Devices::Cuda >(),
-              begin,
-              end,
-              gridXIdx,
-              gridYIdx,
-              gridEntityParameters... );
- 
-   // only launches into the stream 0 are synchronized
-   if( stream == 0 )
-   {
-      cudaStreamSynchronize( s );
-      checkCudaDevice;
+      // only launches into the stream 0 are synchronized
+      if( stream == 0 )
+      {
+         cudaStreamSynchronize( s );
+         TNL_CHECK_CUDA_DEVICE;
+      }
    }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+/****
+ * 2D traverser, MIC
+ */
+template< typename Real,
+          typename Index >
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary,
+         int YOrthogonalBoundary,
+      typename... GridEntityParameters >
+void
+GridTraverser< Meshes::Grid< 2, Real, Devices::MIC, Index > >::
+processEntities(
+   const GridPointer& gridPointer,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   SharedPointer< UserData, DeviceType >& userDataPointer,
+   const int& stream,
+   const GridEntityParameters&... gridEntityParameters )
+{
+        
+    
+#ifdef HAVE_MIC   
+   Devices::MIC::synchronizeDevice();
+
+    //TOHLE JE PRUSER -- nemim poslat vypustku -- 
+    //GridEntity entity( gridPointer.template getData< Devices::MIC >(), begin, gridEntityParameters... );
+
+
+    Devices::MICHider<const GridType> hMicGrid;
+    hMicGrid.pointer=& gridPointer.template getData< Devices::MIC >();
+    Devices::MICHider<UserData> hMicUserData;
+    hMicUserData.pointer=& userDataPointer.template modifyData<Devices::MIC>();
+    TNLMICSTRUCT(begin, const CoordinatesType);
+    TNLMICSTRUCT(end, const CoordinatesType);
+
+    #pragma offload target(mic) in(sbegin,send,hMicUserData,hMicGrid)  
+    {
+        
+        #pragma omp parallel firstprivate( sbegin, send )
+        {     
+            TNLMICSTRUCTUSE(begin, const CoordinatesType);
+            TNLMICSTRUCTUSE(end, const CoordinatesType);    
+            GridEntity entity( *(hMicGrid.pointer), *(kernelbegin) );
+          
+            if( processOnlyBoundaryEntities )
+             {      
+               if( YOrthogonalBoundary )
+                  #pragma omp for
+                  for( auto k = kernelbegin->x();
+                       k <= kernelend->x();
+                       k ++ )
+                  {
+                     entity.getCoordinates().x() = k;
+                     entity.getCoordinates().y() = kernelbegin->y();
+                     entity.refresh();
+                     EntitiesProcessor::processEntity( entity.getMesh(), *(hMicUserData.pointer), entity );
+                     entity.getCoordinates().y() = kernelend->y();
+                     entity.refresh();
+                     EntitiesProcessor::processEntity( entity.getMesh(), *(hMicUserData.pointer), entity );
+                  }
+               if( XOrthogonalBoundary )
+                  #pragma omp for
+                  for( auto k = kernelbegin->y();
+                       k <= kernelend->y();
+                       k ++ )
+                  {
+                     entity.getCoordinates().y() = k;
+                     entity.getCoordinates().x() = kernelbegin->x();
+                     entity.refresh();
+                     EntitiesProcessor::processEntity( entity.getMesh(), *(hMicUserData.pointer), entity );
+                     entity.getCoordinates().x() = kernelend->x();
+                     entity.refresh();
+                     EntitiesProcessor::processEntity( entity.getMesh(), *(hMicUserData.pointer), entity );
+                  }
+             }
+            else
+            {
+                  #pragma omp for
+                  for( IndexType y = kernelbegin->y(); y <= kernelend->y(); y ++ )
+                     for( IndexType x = kernelbegin->x(); x <= kernelend->x(); x ++ )
+                     {
+                        // std::cerr << x << "   " <<y << std::endl;
+                        entity.getCoordinates().x() = x;
+                        entity.getCoordinates().y() = y;
+                        entity.refresh();
+                        EntitiesProcessor::processEntity( entity.getMesh(), *(hMicUserData.pointer), entity );
+                     }      
+             }
+        }
+    }
+      
 #endif
 }
 
@@ -510,17 +839,15 @@ GridTraverser3D(
    UserData* userData,
    const typename GridEntity::CoordinatesType begin,
    const typename GridEntity::CoordinatesType end,
-   const Index gridXIdx,
-   const Index gridYIdx,
-   const Index gridZIdx,
+   const dim3 gridIdx,
    const GridEntityParameters... gridEntityParameters )
 {
    typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType;
    typename GridType::CoordinatesType coordinates;
 
-   coordinates.x() = begin.x() + ( gridXIdx * Devices::Cuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = begin.y() + ( gridYIdx * Devices::Cuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-   coordinates.z() = begin.z() + ( gridZIdx * Devices::Cuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
+   coordinates.x() = begin.x() + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.y() = begin.y() + Devices::Cuda::getGlobalThreadIdx_y( gridIdx );
+   coordinates.z() = begin.z() + Devices::Cuda::getGlobalThreadIdx_z( gridIdx );
 
    if( coordinates <= end )
    {
@@ -535,6 +862,117 @@ GridTraverser3D(
       }
    }
 }
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities,
+          typename... GridEntityParameters >
+__global__ void 
+GridTraverser3DBoundaryAlongXY(
+   const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid,
+   UserData* userData,
+   const Index beginX,
+   const Index endX,
+   const Index beginY,
+   const Index endY,   
+   const Index fixedZ,
+   const dim3 gridIdx,
+   const GridEntityParameters... gridEntityParameters )
+{
+   typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = beginX + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.y() = beginY + Devices::Cuda::getGlobalThreadIdx_y( gridIdx );
+   coordinates.z() = fixedZ;  
+   
+   if( coordinates.x() <= endX && coordinates.y() <= endY )
+   {
+      GridEntity entity( *grid, coordinates, gridEntityParameters... );
+      entity.refresh();
+      EntitiesProcessor::processEntity
+      ( *grid,
+        *userData,
+        entity );
+   }
+}
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities,
+          typename... GridEntityParameters >
+__global__ void 
+GridTraverser3DBoundaryAlongXZ(
+   const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid,
+   UserData* userData,
+   const Index beginX,
+   const Index endX,
+   const Index beginZ,
+   const Index endZ,   
+   const Index fixedY,
+   const dim3 gridIdx,
+   const GridEntityParameters... gridEntityParameters )
+{
+   typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = beginX + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.y() = fixedY;
+   coordinates.z() = beginZ + Devices::Cuda::getGlobalThreadIdx_y( gridIdx );
+   
+   if( coordinates.x() <= endX && coordinates.z() <= endZ )
+   {
+      GridEntity entity( *grid, coordinates, gridEntityParameters... );
+      entity.refresh();
+      EntitiesProcessor::processEntity
+      ( *grid,
+        *userData,
+        entity );
+   }   
+}
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities,
+          typename... GridEntityParameters >
+__global__ void 
+GridTraverser3DBoundaryAlongYZ(
+   const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid,
+   UserData* userData,
+   const Index beginY,
+   const Index endY,
+   const Index beginZ,
+   const Index endZ,   
+   const Index fixedX,
+   const dim3 gridIdx,
+   const GridEntityParameters... gridEntityParameters )
+{
+   typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = fixedX;
+   coordinates.y() = beginY + Devices::Cuda::getGlobalThreadIdx_x( gridIdx );
+   coordinates.z() = beginZ + Devices::Cuda::getGlobalThreadIdx_y( gridIdx );
+   
+   if( coordinates.y() <= endY && coordinates.z() <= endZ )
+   {
+      GridEntity entity( *grid, coordinates, gridEntityParameters... );
+      entity.refresh();
+      EntitiesProcessor::processEntity
+      ( *grid,
+        *userData,
+        entity );
+   }   
+}
 #endif
 
 template< typename Real,
@@ -559,6 +997,190 @@ processEntities(
    const GridEntityParameters&... gridEntityParameters )
 {
 #ifdef HAVE_CUDA   
+   if( processOnlyBoundaryEntities && 
+      ( GridEntity::getMeshDimension() == 3 || GridEntity::getMeshDimension() == 0 ) )
+   {
+      dim3 cudaBlockSize( 16, 16 );
+      const IndexType entitiesAlongX = end.x() - begin.x() + 1;
+      const IndexType entitiesAlongY = end.y() - begin.y() + 1;
+      const IndexType entitiesAlongZ = end.z() - begin.z() + 1;
+      
+      dim3 cudaBlocksCountAlongXY, cudaBlocksCountAlongXZ, cudaBlocksCountAlongYZ,
+           cudaGridsCountAlongXY, cudaGridsCountAlongXZ, cudaGridsCountAlongYZ;
+      
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongXY, cudaGridsCountAlongXY, entitiesAlongX, entitiesAlongY );
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongXZ, cudaGridsCountAlongXZ, entitiesAlongX, entitiesAlongZ - 2 );
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongYZ, cudaGridsCountAlongYZ, entitiesAlongY - 2, entitiesAlongZ - 2 );
+
+      auto& pool = CudaStreamPool::getInstance();
+      Devices::Cuda::synchronizeDevice();
+      
+      const cudaStream_t& s1 = pool.getStream( stream );
+      const cudaStream_t& s2 = pool.getStream( stream + 1 );
+      const cudaStream_t& s3 = pool.getStream( stream + 2 );
+      const cudaStream_t& s4 = pool.getStream( stream + 3 );
+      const cudaStream_t& s5 = pool.getStream( stream + 4 );
+      const cudaStream_t& s6 = pool.getStream( stream + 5 );
+      
+      dim3 gridIdx, gridSize;
+      for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongXY.y; gridIdx.y++ )
+         for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongXY.x; gridIdx.x++ )
+         {
+            Devices::Cuda::setupGrid( cudaBlocksCountAlongXY, cudaGridsCountAlongXY, gridIdx, gridSize );
+            GridTraverser3DBoundaryAlongXY< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongXY, cudaBlockSize, 0 , s1 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.x(),
+                    end.x(),
+                    begin.y(),
+                    end.y(),
+                    begin.z(),
+                    gridIdx,
+                    gridEntityParameters... );
+            GridTraverser3DBoundaryAlongXY< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongXY, cudaBlockSize, 0, s2 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.x(),
+                    end.x(),
+                    begin.y(),
+                    end.y(),
+                    end.z(),
+                    gridIdx,
+                    gridEntityParameters... );
+         }
+      for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongXZ.y; gridIdx.y++ )
+         for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongXZ.x; gridIdx.x++ )
+         {
+            Devices::Cuda::setupGrid( cudaBlocksCountAlongXZ, cudaGridsCountAlongXZ, gridIdx, gridSize );
+            GridTraverser3DBoundaryAlongXZ< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongXZ, cudaBlockSize, 0, s3 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.x(),
+                    end.x(),               
+                    begin.z() + 1,
+                    end.z() - 1,
+                    begin.y(),
+                    gridIdx,
+                    gridEntityParameters... );
+            GridTraverser3DBoundaryAlongXZ< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongXZ, cudaBlockSize, 0, s4 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.x(),
+                    end.x(),               
+                    begin.z() + 1,
+                    end.z() - 1,
+                    end.y(),
+                    gridIdx,
+                    gridEntityParameters... );
+         }
+      for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongYZ.y; gridIdx.y++ )
+         for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongYZ.x; gridIdx.x++ )
+         {
+            Devices::Cuda::setupGrid( cudaBlocksCountAlongYZ, cudaGridsCountAlongYZ, gridIdx, gridSize );
+            GridTraverser3DBoundaryAlongYZ< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongYZ, cudaBlockSize, 0, s5 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.y() + 1,
+                    end.y() - 1,               
+                    begin.z() + 1,
+                    end.z() - 1,
+                    begin.x(),
+                    gridIdx,
+                    gridEntityParameters... );
+            GridTraverser3DBoundaryAlongYZ< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< cudaBlocksCountAlongYZ, cudaBlockSize, 0, s6 >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin.y() + 1,
+                    end.y() - 1,               
+                    begin.z() + 1,
+                    end.z() - 1,
+                    end.x(),
+                    gridIdx,
+                    gridEntityParameters... );
+         }
+      cudaStreamSynchronize( s1 );
+      cudaStreamSynchronize( s2 );
+      cudaStreamSynchronize( s3 );
+      cudaStreamSynchronize( s4 );
+      cudaStreamSynchronize( s5 );
+      cudaStreamSynchronize( s6 );      
+      TNL_CHECK_CUDA_DEVICE;
+   }
+   else
+   {
+      dim3 cudaBlockSize( 8, 8, 8 );
+      dim3 cudaBlocksCount, cudaGridsCount;
+      
+      Devices::Cuda::setupThreads( cudaBlockSize, cudaBlocksCount, cudaGridsCount,
+                                   end.x() - begin.x() + 1,
+                                   end.y() - begin.y() + 1,
+                                   end.z() - begin.z() + 1 );
+
+      auto& pool = CudaStreamPool::getInstance();
+      const cudaStream_t& s = pool.getStream( stream );
+
+      Devices::Cuda::synchronizeDevice();
+      dim3 gridIdx, gridSize;
+      for( gridIdx.z = 0; gridIdx.z < cudaGridsCount.z; gridIdx.z ++ )
+         for( gridIdx.y = 0; gridIdx.y < cudaGridsCount.y; gridIdx.y ++ )
+            for( gridIdx.x = 0; gridIdx.x < cudaGridsCount.x; gridIdx.x ++ )
+            {
+               Devices::Cuda::setupGrid( cudaBlocksCount, cudaGridsCount, gridIdx, gridSize );
+               GridTraverser3D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities, GridEntityParameters... >
+                  <<< gridSize, cudaBlockSize, 0, s >>>
+                  ( &gridPointer.template getData< Devices::Cuda >(),
+                    &userDataPointer.template modifyData< Devices::Cuda >(),
+                    begin,
+                    end,
+                    gridIdx,
+                    gridEntityParameters... );
+            }
+
+      // only launches into the stream 0 are synchronized
+      if( stream == 0 )
+      {
+         cudaStreamSynchronize( s );
+         TNL_CHECK_CUDA_DEVICE;
+      }
+   }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+/****
+ * 3D traverser, MIC
+ */
+template< typename Real,
+          typename Index >
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary,
+         int YOrthogonalBoundary,
+         int ZOrthogonalBoundary,
+      typename... GridEntityParameters >
+void
+GridTraverser< Meshes::Grid< 3, Real, Devices::MIC, Index > >::
+processEntities(
+   const GridPointer& gridPointer,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   SharedPointer< UserData, DeviceType >& userDataPointer,
+   const int& stream,
+   const GridEntityParameters&... gridEntityParameters )
+{
+    std::cout << "Not Implemented yet Grid Traverser <3, Real, Device::MIC>" << std::endl;
+    
+/* HAVE_CUDA   
    dim3 cudaBlockSize( 8, 8, 8 );
    dim3 cudaBlocks;
    cudaBlocks.x = Devices::Cuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
@@ -592,7 +1214,7 @@ processEntities(
       cudaStreamSynchronize( s );
       checkCudaDevice;
    }
-#endif
+ */
 }
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h b/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8f3a999b90a08e02b9bcb2cfb29b0270476f046
--- /dev/null
+++ b/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h
@@ -0,0 +1,173 @@
+/***************************************************************************
+                          NeighborGridEntitiesStorage.h  -  description
+                             -------------------
+    begin                : Dec 18, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
+#include <TNL/Meshes/GridEntityConfig.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
+
+namespace TNL {
+namespace Meshes {
+
+template< typename GridEntity,
+          int NeighborEntityDimension,
+          typename GridEntityConfig,
+          bool storage = GridEntityConfig::template neighborEntityStorage< GridEntity >( NeighborEntityDimension ) >
+class NeighborGridEntityLayer{};   
+   
+template< typename GridEntity,
+          int NeighborEntityDimension,
+          typename GridEntityConfig >
+class NeighborGridEntityLayer< GridEntity, NeighborEntityDimension, GridEntityConfig, true >
+: public NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig >
+{
+   public:
+ 
+      typedef NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig > BaseType;
+      typedef NeighborGridEntityGetter< GridEntity, NeighborEntityDimension > NeighborEntityGetterType;
+
+      using BaseType::getNeighborEntities;
+ 
+      __cuda_callable__
+      NeighborGridEntityLayer( const GridEntity& entity )
+      : BaseType( entity ),
+        neighborEntities( entity )
+      {}
+ 
+      __cuda_callable__
+      const NeighborEntityGetterType& getNeighborEntities( const MeshDimensionTag< NeighborEntityDimension>& tag ) const
+      {
+         return this->neighborEntities;
+      }
+ 
+      __cuda_callable__
+      void refresh( const typename GridEntity::GridType& grid,
+                    const typename GridEntity::GridType::IndexType& entityIndex )
+      {
+         BaseType::refresh( grid, entityIndex );
+         neighborEntities.refresh( grid, entityIndex );
+      }
+ 
+   protected:
+ 
+      NeighborEntityGetterType neighborEntities;
+};
+
+template< typename GridEntity,
+          typename GridEntityConfig >
+class NeighborGridEntityLayer< GridEntity, 0, GridEntityConfig, true >
+{
+   public:
+ 
+      typedef NeighborGridEntityGetter< GridEntity, 0 > NeighborEntityGetterType;
+ 
+      __cuda_callable__
+      NeighborGridEntityLayer( const GridEntity& entity )
+      : neighborEntities( entity )
+      {}
+
+      __cuda_callable__
+      const NeighborEntityGetterType& getNeighborEntities( const MeshDimensionTag< 0 >& tag ) const
+      {
+         return this->neighborEntities;
+      }
+ 
+      __cuda_callable__
+      void refresh( const typename GridEntity::GridType& grid,
+                    const typename GridEntity::GridType::IndexType& entityIndex )
+      {
+         neighborEntities.refresh( grid, entityIndex );
+      }
+ 
+   protected:
+ 
+      NeighborEntityGetterType neighborEntities;
+};
+
+template< typename GridEntity,
+          int NeighborEntityDimension,
+          typename GridEntityConfig >
+class NeighborGridEntityLayer< GridEntity, NeighborEntityDimension, GridEntityConfig, false >
+: public NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig >
+{
+   public:
+      
+      typedef NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig > BaseType;      
+      typedef NeighborGridEntityGetter< GridEntity, NeighborEntityDimension > NeighborEntityGetterType;
+
+      using BaseType::getNeighborEntities;
+ 
+      __cuda_callable__
+      NeighborGridEntityLayer( const GridEntity& entity )
+      : BaseType( entity )
+      {}
+
+      __cuda_callable__
+      const NeighborEntityGetterType& getNeighborEntities( const MeshDimensionTag< NeighborEntityDimension >& tag ) const {}
+ 
+      __cuda_callable__
+      void refresh( const typename GridEntity::GridType& grid,
+                    const typename GridEntity::GridType::IndexType& entityIndex ) {}
+};
+
+template< typename GridEntity,
+          typename GridEntityConfig >
+class NeighborGridEntityLayer< GridEntity, 0, GridEntityConfig, false >
+{
+   public:
+      
+      typedef NeighborGridEntityGetter< GridEntity, 0 > NeighborEntityGetterType;
+         
+      __cuda_callable__
+      NeighborGridEntityLayer( const GridEntity& entity ){}
+
+      __cuda_callable__
+      const NeighborEntityGetterType& getNeighborEntities( const MeshDimensionTag< 0 >& tag ) const {}
+ 
+      __cuda_callable__
+      void refresh( const typename GridEntity::GridType& grid,
+                    const typename GridEntity::GridType::IndexType& entityIndex ) {}
+};
+
+
+
+
+template< typename GridEntity,
+          typename GridEntityConfig >
+class NeighborGridEntitiesStorage
+: public NeighborGridEntityLayer< GridEntity, GridEntity::getMeshDimension(), GridEntityConfig >
+{
+   typedef NeighborGridEntityLayer< GridEntity, GridEntity::getMeshDimension(), GridEntityConfig > BaseType;
+ 
+   public:
+ 
+      using BaseType::getNeighborEntities;
+      using BaseType::refresh;
+ 
+      __cuda_callable__
+      NeighborGridEntitiesStorage( const GridEntity& entity )
+      : BaseType( entity )
+      {}
+ 
+      template< int EntityDimension >
+      __cuda_callable__
+      const NeighborGridEntityGetter< GridEntity, EntityDimension >&
+      getNeighborEntities() const
+      {
+         return BaseType::getNeighborEntities( MeshDimensionTag< EntityDimension >() );
+      }
+};
+
+
+} // namespace Meshes
+} // namespace TNL
+
diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h
similarity index 72%
rename from src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h
rename to src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h
index 3bf6d56900178efec502afab32bd7c8d815279fd..84a9c56d9389f31c013206c10f63fceb81ec2e0c 100644
--- a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h
+++ b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          NeighbourGridEntityGetter.h  -  description
+                          NeighborGridEntityGetter.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -11,32 +11,33 @@
 #pragma once
 
 #include <TNL/Assert.h>
+#include <TNL/Devices/Cuda.h>
 #include <TNL/Meshes/GridEntityConfig.h>
 
 namespace TNL {
 namespace Meshes {
 
 template< typename GridEntity,
-          int NeighbourEntityDimensions,
+          int NeighborEntityDimension,
           typename EntityStencilTag =
-            GridEntityStencilStorageTag< GridEntity::ConfigType::template neighbourEntityStorage< GridEntity >( NeighbourEntityDimensions ) > >
-class NeighbourGridEntityGetter
+            GridEntityStencilStorageTag< GridEntity::ConfigType::template neighborEntityStorage< GridEntity >( NeighborEntityDimension ) > >
+class NeighborGridEntityGetter
 {
    public:
 
       // TODO: not all specializations are implemented yet
  
       __cuda_callable__
-      NeighbourGridEntityGetter( const GridEntity& entity )
+      NeighborGridEntityGetter( const GridEntity& entity )
       {
-         //Assert( false, );
+         //TNL_ASSERT( false, );
       }
  
       __cuda_callable__
       void refresh( const typename GridEntity::GridType& grid,
                     const typename GridEntity::IndexType& entityIndex )
       {
-         //Assert( false, );
+         //TNL_ASSERT( false, );
       }
 
 };
diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter1D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h
similarity index 51%
rename from src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter1D_impl.h
rename to src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h
index ec0509da104c6df20d35d70c0505497042ede582..14143220eb451521afb6098e67ebc9889559a68a 100644
--- a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter1D_impl.h
+++ b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          NeighbourGridEntityGetter1D_impl.h  -  description
+                          NeighborGridEntityGetter1D_impl.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 #include <TNL/Meshes/GridDetails/Grid1D.h>
 #include <TNL/Meshes/GridDetails/Grid2D.h>
 #include <TNL/Meshes/GridDetails/Grid3D.h>
@@ -21,7 +21,7 @@ namespace Meshes {
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       1         |              1            |       ----        |
  * +-----------------+---------------------------+-------------------+
@@ -30,59 +30,53 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >,
    1,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 1;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 1;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( this->entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    this->entity.getCoordinates() < this->entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << this->entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + step;
       }
  
@@ -97,7 +91,7 @@ class NeighbourGridEntityGetter<
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       1         |              1            |  Cross/Full       |
  * +-----------------+---------------------------+-------------------+
@@ -107,62 +101,56 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >,
    1,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 1;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 1;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
-      typedef NeighbourGridEntityGetter< GridEntityType, 1, StencilStorage > ThisType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
+      typedef NeighborGridEntityGetter< GridEntityType, 1, StencilStorage > ThisType;
  
       static const int stencilSize = Config::getStencilSize();
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( this->entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    this->entity.getCoordinates() < this->entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << this->entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + step ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + step ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
 #ifndef HAVE_CUDA  // TODO: fix it -- does not work with nvcc
          if( step < -stencilSize || step > stencilSize )
             return this->entity.getIndex() + step;
@@ -179,9 +167,9 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencil[ index + stencilSize ] = entityIndex + index;
+               neighborEntityGetter.stencil[ index + stencilSize ] = entityIndex + index;
             }
       };
  
@@ -202,7 +190,7 @@ class NeighbourGridEntityGetter<
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       1         |              0            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -211,59 +199,53 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >,
    0,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 1;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 1;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step + ( step < 0 ) <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step + ( step < 0 ) ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step + ( step < 0 ) ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ).x() &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ).x() &&
                     entity.getCoordinates().x() + step + ( step < 0 ) <= entity.getMesh().getDimensions().x(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + step + ( step < 0 );
       }
  
@@ -274,13 +256,13 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
  
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       0         |              1            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -290,25 +272,25 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >,
    1,
    StencilStorage > //GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 0;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 0;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
@@ -316,35 +298,29 @@ class NeighbourGridEntityGetter<
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step - ( step > 0 ) >= 0 &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= 0 &&
                     entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions().x(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + step - ( step > 0 );
       }
  
@@ -358,7 +334,7 @@ class NeighbourGridEntityGetter<
 
 /****   TODO: Implement this, now it is only a copy of specialization for none stencil storage
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       0         |              1            |       Cross       |
  * +-----------------+---------------------------+-------------------+
@@ -367,60 +343,54 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >,
    1,
    GridEntityStencilStorageTag< GridEntityCrossStencil > >
 {
    public:
  
-      static const int EntityDimensions = 0;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 0;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
 
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + step - ( step > 0 );
       }
  
@@ -435,7 +405,7 @@ class NeighbourGridEntityGetter<
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       0         |              0            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -444,59 +414,53 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >,
    0,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 0;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 0;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int step >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
       }
  
       template< int step >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
                     entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
 
          return this->entity.getIndex() + step;
       }
@@ -511,5 +475,4 @@ class NeighbourGridEntityGetter<
 };
 
 } // namespace Meshes
-} // namespace TNL
-
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter2D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h
similarity index 62%
rename from src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter2D_impl.h
rename to src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h
index 45f3e225a99a56f5c522794deab57aa81ab30cb3..b760748cd23a84552891d095f9053058d4b012ca 100644
--- a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter2D_impl.h
+++ b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          NeighbourGridEntityGetter2D_impl.h  -  description
+                          NeighborGridEntityGetter2D_impl.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 #include <TNL/Meshes/GridDetails/Grid1D.h>
 #include <TNL/Meshes/GridDetails/Grid2D.h>
 #include <TNL/Meshes/GridDetails/Grid3D.h>
@@ -20,7 +20,7 @@ namespace Meshes {
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              2            | No specialization |
  * +-----------------+---------------------------+-------------------+
@@ -30,43 +30,40 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    2,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->grid,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX,
                                                           entity.getCoordinates().y() + stepY ) );
       }
@@ -75,16 +72,13 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX;
       }
  
@@ -95,12 +89,12 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              2            |       Cross       |
  * +-----------------+---------------------------+-------------------+
@@ -109,48 +103,45 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    2,
    GridEntityStencilStorageTag< GridEntityCrossStencil > >
 {
    public:
  
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef GridEntityStencilStorageTag< GridEntityCrossStencil > StencilStorage;
-      typedef NeighbourGridEntityGetter< GridEntityType, 2, StencilStorage > ThisType;
+      typedef NeighborGridEntityGetter< GridEntityType, 2, StencilStorage > ThisType;
  
  
       static const int stencilSize = Config::getStencilSize();
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-            return NeighbourGridEntityType( this->entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+            return NeighborGridEntityType( this->entity.getMesh(),
                                             CoordinatesType( entity.getCoordinates().x() + stepX,
                                                              entity.getCoordinates().y() + stepY ) );
       }
@@ -159,16 +150,13 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
 #ifndef HAVE_CUDA // TODO: fix this to work with CUDA
          if( ( stepX != 0 && stepY != 0 ) ||
              ( stepX < -stencilSize || stepX > stencilSize ||
@@ -189,9 +177,9 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
+               neighborEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
             }
       };
 
@@ -201,10 +189,10 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilY[ index + stencilSize ] =
-                  entityIndex + index * neighbourEntityGetter.entity.getMesh().getDimensions().x();
+               neighborEntityGetter.stencilY[ index + stencilSize ] =
+                  entityIndex + index * neighborEntityGetter.entity.getMesh().getDimensions().x();
             }
       };
 
@@ -226,12 +214,12 @@ class NeighbourGridEntityGetter<
       IndexType stencilX[ 2 * stencilSize + 1 ];
       IndexType stencilY[ 2 * stencilSize + 1 ];
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              1            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -241,42 +229,38 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    1,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef typename GridEntityType::EntityOrientationType EntityOrientationType;
       typedef typename GridEntityType::EntityBasisType EntityBasisType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( ! stepX + ! stepY == 1,
-                    std::cerr << "Only one of the steps can be non-zero: stepX = " << stepX << " stepY = " << stepY );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         static_assert( ! stepX + ! stepY == 1, "Only one of the steps can be non-zero." );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ) ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() +
@@ -286,8 +270,8 @@ class NeighbourGridEntityGetter<
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ) ),
                                          EntityOrientationType( stepX ? (stepX > 0 ? 1 : -1) : 0,
@@ -312,7 +296,7 @@ class NeighbourGridEntityGetter<
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |            0              |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -322,40 +306,37 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    0,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( stepX != 0 && stepY != 0,
+         TNL_ASSERT( stepX != 0 && stepY != 0,
                     std::cerr << " stepX = " << stepX << " stepY = " << stepY );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
@@ -364,8 +345,8 @@ class NeighbourGridEntityGetter<
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
                    << " entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ) ) = "
                    << entity.getMesh().getDimensions()  + CoordinatesType( sign( stepX ), sign( stepY ) )
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->grid,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ) ) );
       }
@@ -384,12 +365,12 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       1         |              2            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -399,42 +380,39 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 1, Config >,
    2,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 1;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 1;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         /*Assert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
+         /*TNL_ASSERT( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
                     ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ),
                     std::cerr << "( stepX, stepY ) cannot be perpendicular to entity coordinates: stepX = " << stepX << " stepY = " << stepY
                          << " entity.getOrientation() = " << entity.getOrientation() );*/
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions() + entity.getOrientation(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() + entity.getOrientation() = " << entity.getMesh().getDimensions() + entity.getOrientation()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
                                         stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() +
@@ -443,8 +421,8 @@ class NeighbourGridEntityGetter<
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 )  * ( entity.getOrientation().x() != 0.0 ), stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(),
                      CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
                                       entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) );
       }
@@ -466,7 +444,7 @@ class NeighbourGridEntityGetter<
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       0         |              0            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -476,43 +454,40 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 0, Config >,
    0,
    StencilStorage >
 {
    public:
  
-      static const int EntityDimensions = 0;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 0;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->grid,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX,
                                                           entity.getCoordinates().y() + stepY ) );
       }
@@ -521,16 +496,13 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + stepY * ( entity.getMesh().getDimensions().x() + 1 ) + stepX;
       }
  
@@ -541,9 +513,8 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 } // namespace Meshes
 } // namespace TNL
-
diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter3D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h
similarity index 65%
rename from src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter3D_impl.h
rename to src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h
index d4d25ad0b9b824f125e338fd1c017377edbab5b9..a7d2ab6d879cb1779b44dbe56f7f98464cd71473 100644
--- a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter3D_impl.h
+++ b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          NeighbourGridEntityGetter3D_impl.h  -  description
+                          NeighborGridEntityGetter3D_impl.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntityGetter.h>
 #include <TNL/Meshes/GridDetails/Grid1D.h>
 #include <TNL/Meshes/GridDetails/Grid2D.h>
 #include <TNL/Meshes/GridDetails/Grid3D.h>
@@ -21,7 +21,7 @@ namespace Meshes {
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |              3            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -30,43 +30,40 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    3,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 3;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 3;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
                                                       entity.getCoordinates().z() + stepZ ) );
       }
@@ -75,17 +72,14 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX;
       }
  
@@ -96,14 +90,14 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
  
 };
 
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |              3            |       Cross       |
  * +-----------------+---------------------------+-------------------+
@@ -112,47 +106,44 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    3,
    GridEntityStencilStorageTag< GridEntityCrossStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 3;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 3;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef GridEntityStencilStorageTag< GridEntityCrossStencil > StencilStorage;
-      typedef NeighbourGridEntityGetter< GridEntityType, 3, StencilStorage > ThisType;
+      typedef NeighborGridEntityGetter< GridEntityType, 3, StencilStorage > ThisType;
 
       static const int stencilSize = Config::getStencilSize();
  
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
                                                       entity.getCoordinates().z() + stepZ ) );
       }
@@ -161,17 +152,14 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
 #ifndef HAVE_CUDA // TODO: fix this to work with CUDA
          if( ( stepX != 0 && stepY != 0 && stepZ != 0 ) ||
              ( stepX < -stencilSize || stepX > stencilSize ||
@@ -195,9 +183,9 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
+               neighborEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
             }
       };
 
@@ -207,10 +195,10 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilY[ index + stencilSize ] =
-                  entityIndex + index * neighbourEntityGetter.entity.getMesh().getDimensions().x();
+               neighborEntityGetter.stencilY[ index + stencilSize ] =
+                  entityIndex + index * neighborEntityGetter.entity.getMesh().getDimensions().x();
             }
       };
  
@@ -220,10 +208,10 @@ class NeighbourGridEntityGetter<
          public:
  
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilZ[ index + stencilSize ] =
-                  entityIndex + index * neighbourEntityGetter.entity.getMesh().cellZNeighboursStep;
+               neighborEntityGetter.stencilZ[ index + stencilSize ] =
+                  entityIndex + index * neighborEntityGetter.entity.getMesh().cellZNeighborsStep;
             }
       };
 
@@ -248,12 +236,12 @@ class NeighbourGridEntityGetter<
       IndexType stencilY[ 2 * stencilSize + 1 ];
       IndexType stencilZ[ 2 * stencilSize + 1 ];
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |              2            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -262,44 +250,38 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    2,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef typename GridEntityType::EntityOrientationType EntityOrientationType;
       typedef typename GridEntityType::EntityBasisType EntityBasisType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( ! stepX + ! stepY + ! stepZ == 2,
-                    std::cerr << "Only one of the steps can be non-zero: stepX = " << stepX
-                         << " stepY = " << stepY
-                         << " stepZ = " << stepZ );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         static_assert( ! stepX + ! stepY + ! stepZ == 2, "Only one of the steps can be non-zero." );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
@@ -312,8 +294,8 @@ class NeighbourGridEntityGetter<
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ),
                                                           entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ),
@@ -337,12 +319,12 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****      TODO: Finish it, knonw it is only a copy of specialization for none stored stencil
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |              2            |       Cross       |
  * +-----------------+---------------------------+-------------------+
@@ -351,44 +333,38 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    2,
    GridEntityStencilStorageTag< GridEntityCrossStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef typename GridEntityType::EntityOrientationType EntityOrientationType;
       typedef typename GridEntityType::EntityBasisType EntityBasisType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( ! stepX + ! stepY + ! stepZ == 2,
-                    std::cerr << "Only one of the steps can be non-zero: stepX = " << stepX
-                         << " stepY = " << stepY
-                         << " stepZ = " << stepZ );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         static_assert( ! stepX + ! stepY + ! stepZ == 2, "Only one of the steps can be non-zero." );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
@@ -401,8 +377,8 @@ class NeighbourGridEntityGetter<
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( this->entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ),
                                                           entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ),
@@ -426,13 +402,13 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |              1            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -441,44 +417,38 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    1,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 1;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 1;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
       typedef typename GridEntityType::EntityOrientationType EntityOrientationType;
       typedef typename GridEntityType::EntityBasisType EntityBasisType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( ! stepX + ! stepY + ! stepZ == 1,
-                    std::cerr << "Exactly two of the steps must be non-zero: stepX = " << stepX
-                         << " stepY = " << stepY
-                         << " stepZ = " << stepZ );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         static_assert( ! stepX + ! stepY + ! stepZ == 1, "Exactly two of the steps must be non-zero." );
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
@@ -491,8 +461,8 @@ class NeighbourGridEntityGetter<
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                       entity.getCoordinates().y() + stepY + ( stepY < 0 ),
                                                       entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ),
                                      EntityOrientationType( !!stepX, !!stepY, !!stepZ ),
@@ -513,13 +483,13 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       3         |            0              |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -528,42 +498,39 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >,
    0,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 3;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 3;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY,int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( stepX != 0 && stepY != 0 && stepZ != 0,
+         TNL_ASSERT( stepX != 0 && stepY != 0 && stepZ != 0,
                     std::cerr << " stepX = " << stepX
                          << " stepY = " << stepY
                          << " stepZ = " << stepZ );
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
@@ -577,8 +544,8 @@ class NeighbourGridEntityGetter<
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
                    << " entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ), sign( stepZ ) ) = "
                    << entity.getMesh().getDimensions()  + CoordinatesType( sign( stepX ), sign( stepY ), sign( stepZ ) )
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                       entity.getCoordinates().y() + stepY + ( stepY < 0 ),
                                                       entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ) );
       }
@@ -597,12 +564,12 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              3            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -611,44 +578,41 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 2, Config >,
    3,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 3;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 3;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         /*Assert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
+         /*TNL_ASSERT( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
                     ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ) &&
                     ( ( !! stepZ ) == ( !! entity.getOrientation().z() ) ),
                     std::cerr << "( stepX, stepY, stepZ ) cannot be perpendicular to entity coordinates: stepX = " << stepX
                          << " stepY = " << stepY << " stepZ = " << stepZ
                          << " entity.getOrientation() = " << entity.getOrientation() );*/
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getMesh().getDimensions() + entity.getOrientation(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() + entity.getOrientation() = " << entity.getMesh().getDimensions() + entity.getOrientation()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() +
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() +
                        CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
                                         stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ),
                                         stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
@@ -662,8 +626,8 @@ class NeighbourGridEntityGetter<
                         stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ),
                         stepZ + ( stepZ < 0 ) * ( entity.getOrientation().z() != 0.0 ) )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( entity.getMesh(),
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntityType( entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
                                                           entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ),
                                                           entity.getCoordinates().z() + stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) );
@@ -683,12 +647,12 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |
+ * | EntityDimenions | NeighborEntityDimension |  Stored Stencil   |
  * +-----------------+---------------------------+-------------------+
  * |       0         |              0            |       None        |
  * +-----------------+---------------------------+-------------------+
@@ -697,44 +661,41 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class NeighbourGridEntityGetter<
+class NeighborGridEntityGetter<
    GridEntity< Meshes::Grid< 3, Real, Device, Index >, 0, Config >,
    0,
    GridEntityStencilStorageTag< GridEntityNoStencil > >
 {
    public:
  
-      static const int EntityDimensions = 0;
-      static const int NeighbourEntityDimensions = 0;
+      static const int EntityDimension = 0;
+      static const int NeighborEntityDimension = 0;
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetterType;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetterType;
 
       __cuda_callable__ inline
-      NeighbourGridEntityGetter( const GridEntityType& entity )
+      NeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
  
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
-      NeighbourGridEntityType getEntity() const
+      NeighborGridEntityType getEntity() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
+                   << " EntityDimension = " << EntityDimension );
+         return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
                                                       entity.getCoordinates().z() + stepZ ) );
       }
@@ -743,17 +704,14 @@ class NeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         Assert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
-              std::cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
-         Assert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+         TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" );
+         TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" );
+         TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(),
               std::cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
                    << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
-                   << " EntityDimensions = " << EntityDimensions );
+                   << " EntityDimension = " << EntityDimension );
          return this->entity.getIndex() + stepZ * ( entity.getMesh().getDimensions().y() + 1 + stepY ) * ( entity.getMesh().getDimensions().x() + 1 ) + stepX;
       }
  
@@ -764,10 +722,9 @@ class NeighbourGridEntityGetter<
 
       const GridEntityType& entity;
  
-      //NeighbourGridEntityGetter(){};
+      //NeighborGridEntityGetter(){};
  
 };
 
 } // namespace Meshes
-} // namespace TNL
-
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntitiesStorage.h b/src/TNL/Meshes/GridDetails/NeighbourGridEntitiesStorage.h
deleted file mode 100644
index ad2edb43108d768a289493f3c33c16f497a72b1f..0000000000000000000000000000000000000000
--- a/src/TNL/Meshes/GridDetails/NeighbourGridEntitiesStorage.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/***************************************************************************
-                          NeighbourGridEntitiesStorage.h  -  description
-                             -------------------
-    begin                : Dec 18, 2015
-    copyright            : (C) 2015 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/Devices/Cuda.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
-#include <TNL/Meshes/GridEntityConfig.h>
-#include <TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h>
-
-namespace TNL {
-namespace Meshes {
-
-template< typename GridEntity,
-          int NeighbourEntityDimensions,
-          typename GridEntityConfig,
-          bool storage = GridEntityConfig::template neighbourEntityStorage< GridEntity >( NeighbourEntityDimensions ) >
-class NeighbourGridEntityLayer{};   
-   
-template< typename GridEntity,
-          int NeighbourEntityDimensions,
-          typename GridEntityConfig >
-class NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions, GridEntityConfig, true >
-: public NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1, GridEntityConfig >
-{
-   public:
- 
-      typedef NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1, GridEntityConfig > BaseType;
-      typedef NeighbourGridEntityGetter< GridEntity, NeighbourEntityDimensions > NeighbourEntityGetterType;
-
-      using BaseType::getNeighbourEntities;
- 
-      __cuda_callable__
-      NeighbourGridEntityLayer( const GridEntity& entity )
-      : BaseType( entity ),
-        neighbourEntities( entity )
-      {}
- 
-      __cuda_callable__
-      const NeighbourEntityGetterType& getNeighbourEntities( const MeshDimensionsTag< NeighbourEntityDimensions>& tag ) const
-      {
-         return this->neighbourEntities;
-      }
- 
-      __cuda_callable__
-      void refresh( const typename GridEntity::GridType& grid,
-                    const typename GridEntity::GridType::IndexType& entityIndex )
-      {
-         BaseType::refresh( grid, entityIndex );
-         neighbourEntities.refresh( grid, entityIndex );
-      }
- 
-   protected:
- 
-      NeighbourEntityGetterType neighbourEntities;
-};
-
-template< typename GridEntity,
-          typename GridEntityConfig >
-class NeighbourGridEntityLayer< GridEntity, 0, GridEntityConfig, true >
-{
-   public:
- 
-      typedef NeighbourGridEntityGetter< GridEntity, 0 > NeighbourEntityGetterType;
- 
-      __cuda_callable__
-      NeighbourGridEntityLayer( const GridEntity& entity )
-      : neighbourEntities( entity )
-      {}
-
-      __cuda_callable__
-      const NeighbourEntityGetterType& getNeighbourEntities( const MeshDimensionsTag< 0 >& tag ) const
-      {
-         return this->neighbourEntities;
-      }
- 
-      __cuda_callable__
-      void refresh( const typename GridEntity::GridType& grid,
-                    const typename GridEntity::GridType::IndexType& entityIndex )
-      {
-         neighbourEntities.refresh( grid, entityIndex );
-      }
- 
-   protected:
- 
-      NeighbourEntityGetterType neighbourEntities;
-};
-
-template< typename GridEntity,
-          int NeighbourEntityDimensions,
-          typename GridEntityConfig >
-class NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions, GridEntityConfig, false >
-: public NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1, GridEntityConfig >
-{
-   public:
-      
-      typedef NeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1, GridEntityConfig > BaseType;      
-      typedef NeighbourGridEntityGetter< GridEntity, NeighbourEntityDimensions > NeighbourEntityGetterType;
-
-      using BaseType::getNeighbourEntities;
- 
-      __cuda_callable__
-      NeighbourGridEntityLayer( const GridEntity& entity )
-      : BaseType( entity )
-      {}
-
-      __cuda_callable__
-      const NeighbourEntityGetterType& getNeighbourEntities( const MeshDimensionsTag< NeighbourEntityDimensions >& tag ) const {}
- 
-      __cuda_callable__
-      void refresh( const typename GridEntity::GridType& grid,
-                    const typename GridEntity::GridType::IndexType& entityIndex ) {}
-};
-
-template< typename GridEntity,
-          typename GridEntityConfig >
-class NeighbourGridEntityLayer< GridEntity, 0, GridEntityConfig, false >
-{
-   public:
-      
-      typedef NeighbourGridEntityGetter< GridEntity, 0 > NeighbourEntityGetterType;
-         
-      __cuda_callable__
-      NeighbourGridEntityLayer( const GridEntity& entity ){}
-
-      __cuda_callable__
-      const NeighbourEntityGetterType& getNeighbourEntities( const MeshDimensionsTag< 0 >& tag ) const {}
- 
-      __cuda_callable__
-      void refresh( const typename GridEntity::GridType& grid,
-                    const typename GridEntity::GridType::IndexType& entityIndex ) {}
-};
-
-
-
-
-template< typename GridEntity,
-          typename GridEntityConfig >
-class NeighbourGridEntitiesStorage
-: public NeighbourGridEntityLayer< GridEntity, GridEntity::meshDimensions, GridEntityConfig >
-{
-   typedef NeighbourGridEntityLayer< GridEntity, GridEntity::meshDimensions, GridEntityConfig > BaseType;
- 
-   public:
- 
-      using BaseType::getNeighbourEntities;
-      using BaseType::refresh;
- 
-      __cuda_callable__
-      NeighbourGridEntitiesStorage( const GridEntity& entity )
-      : BaseType( entity )
-      {}
- 
-      template< int EntityDimensions >
-      __cuda_callable__
-      const NeighbourGridEntityGetter< GridEntity, EntityDimensions >&
-      getNeighbourEntities() const
-      {
-         return BaseType::getNeighbourEntities( MeshDimensionsTag< EntityDimensions >() );
-      }
-};
-
-
-} // namespace Meshes
-} // namespace TNL
-
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h
index 400f71531a5f6f5d92606d9da52b991839098b94..a9310fd1e54faa1e417086f4c5f85765be4b6974 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h
@@ -25,25 +25,22 @@ class Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >
    public:
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
  
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -57,25 +54,22 @@ class Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >
    public:
       typedef Meshes::Grid< 1, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
  
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h
index 9abc83b529dc3a7f19a55825737c19ff54a549e1..6e8c1e3b2a6b03dca0bdfc0d4e58dbfe6d7280df 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h
@@ -27,12 +27,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary cells
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >(
       gridPointer,
@@ -50,12 +50,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior cells
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -74,12 +74,12 @@ void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::
 processAllEntities(
    const GridPointer& gridPointer,
-   SharedPointer< UserData, DeviceType >& userDataPointer ) const
+   SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All cells
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -100,12 +100,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >(
       gridPointer,
@@ -123,12 +123,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -147,12 +147,12 @@ void
 Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::
 processAllEntities(
    const GridPointer& gridPointer,
-   SharedPointer< UserData, DeviceType >& userDataPointer ) const
+   SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h
index 6123ce9d1a712a916775c45fe3d856e285f8196c..d80205feede8fb2e08cbcd4e92fe91d3c852904f 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h
@@ -25,24 +25,21 @@ class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >
    public:
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -55,25 +52,22 @@ class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >
    public:
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -86,25 +80,22 @@ class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >
    public:
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
       
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h
index 4b57a2642165f3b0804a23d5cc09e83356f307a7..66d03c949733edbc138a9014b5141e7ba84e78ff 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h
@@ -27,12 +27,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary cells
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >(
       gridPointer,
@@ -51,12 +51,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior cells
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -75,12 +75,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All cells
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -102,12 +102,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary faces
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -137,12 +137,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior faces
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -172,12 +172,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All faces
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -207,12 +207,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >(
       gridPointer,
@@ -231,12 +231,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -255,12 +255,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h
index a03503e302bb346cf096d893859fe61fcb4de24d..705e4bbc033ca36708306894ec15186074d9460a 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h
@@ -25,24 +25,21 @@ class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >
    public:
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -55,24 +52,21 @@ class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >
    public:
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -85,25 +79,22 @@ class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >
    public:
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
  
 };
 
@@ -116,25 +107,22 @@ class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >
    public:
       typedef Meshes::Grid< 3, Real, Device, Index > GridType;
       typedef SharedPointer< GridType > GridPointer;
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processBoundaryEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
 
       template< typename UserData,
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridPointer& gridPointer,
-                                    SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                                    SharedPointer< UserData, Device >& userDataPointer ) const;
  
       template< typename UserData,
                 typename EntitiesProcessor >
       void processAllEntities( const GridPointer& gridPointer,
-                               SharedPointer< UserData, DeviceType >& userDataPointer ) const;
+                               SharedPointer< UserData, Device >& userDataPointer ) const;
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h
index 42e16f64f75ca6096966e0c50d41d5f9bd252090..84e44ef17c29aca27da6c940e6ab29841fb9aa86 100644
--- a/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h
@@ -27,12 +27,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary cells
     */
-   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." );
 
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >(
       gridPointer,
@@ -51,12 +51,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior cells
     */
-   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -75,12 +75,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All cells
     */
-   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -102,12 +102,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary faces
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, 0, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -146,12 +146,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior faces
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -190,12 +190,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All faces
     */
-   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." );
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
       CoordinatesType( 0, 0, 0 ),
@@ -236,12 +236,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary edges
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -280,12 +280,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior edges
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
@@ -324,12 +324,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All edges
     */
-   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." );
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >(
       gridPointer,
       CoordinatesType( 0, 0, 0 ),
@@ -370,12 +370,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Boundary vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >(
       gridPointer,
@@ -394,12 +394,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::
 processInteriorEntities( const GridPointer& gridPointer,
-                         SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                         SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * Interior vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
@@ -418,12 +418,12 @@ template< typename Real,
 void
 Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::
 processAllEntities( const GridPointer& gridPointer,
-                    SharedPointer< UserData, DeviceType >& userDataPointer ) const
+                    SharedPointer< UserData, Device >& userDataPointer ) const
 {
    /****
     * All vertices
     */
-   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." );
  
    GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
       gridPointer,
diff --git a/src/TNL/Meshes/GridEntity.h b/src/TNL/Meshes/GridEntity.h
index aa70096e36a3749deb73838ea312c74e34fdd432..4db50173285c267e61736a36827073dcb323a002 100644
--- a/src/TNL/Meshes/GridEntity.h
+++ b/src/TNL/Meshes/GridEntity.h
@@ -10,15 +10,15 @@
 
 #pragma once
 
-#include <TNL/Meshes/GridDetails/NeighbourGridEntitiesStorage.h>
+#include <TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h>
 
 namespace TNL {
 namespace Meshes {
 
 template< typename GridEntity,
-          int NeighbourEntityDimensions,
+          int NeighborEntityDimension,
           typename StencilStorage >
-class NeighbourGridEntityGetter;
+class NeighborGridEntityGetter;
 
 template< typename GridEntityType >
 class BoundaryGridEntityChecker;
@@ -28,51 +28,47 @@ class GridEntityCenterGetter;
 
 
 template< typename Grid,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 class GridEntity
 {
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
-class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions, Config >
+class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
       typedef GridType MeshType;
       typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       typedef Config ConfigType;
  
-      static const int meshDimensions = GridType::meshDimensions;
+      constexpr static int getMeshDimension() { return GridType::getMeshDimension(); };            
  
-      static const int entityDimensions = EntityDimensions;
+      constexpr static int getEntityDimension() { return EntityDimension; };
  
-      constexpr static int getDimensions() { return EntityDimensions; };
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityOrientationType;
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityBasisType;
+      typedef GridEntity< GridType, EntityDimension, Config > ThisType;
+      typedef typename GridType::PointType PointType;
  
-      constexpr static int getMeshDimensions() { return meshDimensions; };            
+      typedef NeighborGridEntitiesStorage< ThisType, Config > NeighborGridEntitiesStorageType;
  
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType;
-      typedef GridEntity< GridType, entityDimensions, Config > ThisType;
-      typedef typename GridType::VertexType VertexType;
- 
-      typedef NeighbourGridEntitiesStorage< ThisType, Config > NeighbourGridEntitiesStorageType;
- 
-      template< int NeighbourEntityDimensions = entityDimensions >
-      using NeighbourEntities =
-         NeighbourGridEntityGetter<
-            GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >,
-                           EntityDimensions,
+      template< int NeighborEntityDimension = getEntityDimension() >
+      using NeighborEntities =
+         NeighborGridEntityGetter<
+            GridEntity< Meshes::Grid< Dimension, Real, Device, Index >,
+                           EntityDimension,
                            Config >,
-            NeighbourEntityDimensions >;
+            NeighborEntityDimension >;
  
       __cuda_callable__ inline
       GridEntity( const GridType& grid );
@@ -116,16 +112,16 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensi
       __cuda_callable__ inline
       void setBasis( const EntityBasisType& basis );
  
-      template< int NeighbourEntityDimensions = entityDimensions >
+      template< int NeighborEntityDimension = getEntityDimension() >
       __cuda_callable__ inline
-      const NeighbourEntities< NeighbourEntityDimensions >&
-      getNeighbourEntities() const;
+      const NeighborEntities< NeighborEntityDimension >&
+      getNeighborEntities() const;
  
       __cuda_callable__ inline
       bool isBoundaryEntity() const;
  
       __cuda_callable__ inline
-      VertexType getCenter() const;
+      PointType getCenter() const;
  
       __cuda_callable__ inline
       const RealType& getMeasure() const;
@@ -145,7 +141,7 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensi
  
       EntityBasisType basis;
  
-      NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
+      NeighborGridEntitiesStorageType neighborEntitiesStorage;
  
       //__cuda_callable__ inline
       //GridEntity();
@@ -158,44 +154,40 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensi
 /****
  * Specializations for cells
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
-class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >
+class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
       typedef GridType MeshType;
       typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef Config ConfigType;
  
-      static const int meshDimensions = GridType::meshDimensions;
- 
-      static const int entityDimensions = meshDimensions;
-
-      constexpr static int getDimensions() { return entityDimensions; };
+      constexpr static int getMeshDimension() { return GridType::getMeshDimension(); };
  
-      constexpr static int getMeshDimensions() { return meshDimensions; };
+      constexpr static int getEntityDimension() { return getMeshDimension(); };
  
  
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType;
-      typedef GridEntity< GridType, entityDimensions, Config > ThisType;
-      typedef NeighbourGridEntitiesStorage< ThisType, Config > NeighbourGridEntitiesStorageType;
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityOrientationType;
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityBasisType;
+      typedef GridEntity< GridType, Dimension, Config > ThisType;
+      typedef NeighborGridEntitiesStorage< ThisType, Config > NeighborGridEntitiesStorageType;
  
-      template< int NeighbourEntityDimensions = entityDimensions >
-      using NeighbourEntities =
-         NeighbourGridEntityGetter<
-            GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >,
-                           entityDimensions,
+      template< int NeighborEntityDimension = getEntityDimension() >
+      using NeighborEntities =
+         NeighborGridEntityGetter<
+            GridEntity< Meshes::Grid< Dimension, Real, Device, Index >,
+                           Dimension,
                            Config >,
-            NeighbourEntityDimensions >;
+            NeighborEntityDimension >;
 
 
       __cuda_callable__ inline
@@ -240,22 +232,22 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, C
       __cuda_callable__ inline
       void setBasis( const EntityBasisType& basis ){};
  
-      template< int NeighbourEntityDimensions = Dimensions >
+      template< int NeighborEntityDimension = Dimension >
       __cuda_callable__ inline
-      const NeighbourEntities< NeighbourEntityDimensions >&
-      getNeighbourEntities() const;
+      const NeighborEntities< NeighborEntityDimension >&
+      getNeighborEntities() const;
  
       __cuda_callable__ inline
       bool isBoundaryEntity() const;
  
       __cuda_callable__ inline
-      VertexType getCenter() const;
+      PointType getCenter() const;
  
       __cuda_callable__ inline
       const RealType& getMeasure() const;
  
       __cuda_callable__ inline
-      const VertexType& getEntityProportions() const;
+      const PointType& getEntityProportions() const;
  
       __cuda_callable__ inline
       const GridType& getMesh() const;
@@ -268,7 +260,7 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, C
  
       CoordinatesType coordinates;
  
-      NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
+      NeighborGridEntitiesStorageType neighborEntitiesStorage;
  
       //__cuda_callable__ inline
       //GridEntity();
@@ -281,43 +273,39 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, C
 /****
  * Specialization for vertices
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
-class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >
+class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
       typedef GridType MeshType;
       typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef Config ConfigType;
  
-      static const int meshDimensions = GridType::meshDimensions;
- 
-      static const int entityDimensions = 0;
- 
-      constexpr static int getDimensions() { return entityDimensions; };
+      constexpr static int getMeshDimension() { return GridType::getMeshDimension(); };
  
-      constexpr static int getMeshDimensions() { return meshDimensions; };
+      constexpr static int getEntityDimension() { return 0; };
  
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType;
-      typedef GridEntity< GridType, entityDimensions, Config > ThisType;
-      typedef NeighbourGridEntitiesStorage< ThisType, Config > NeighbourGridEntitiesStorageType;
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityOrientationType;
+      typedef Containers::StaticVector< getMeshDimension(), IndexType > EntityBasisType;
+      typedef GridEntity< GridType, 0, Config > ThisType;
+      typedef NeighborGridEntitiesStorage< ThisType, Config > NeighborGridEntitiesStorageType;
  
-      template< int NeighbourEntityDimensions = entityDimensions >
-      using NeighbourEntities =
-         NeighbourGridEntityGetter<
-            GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >,
-                           entityDimensions,
+      template< int NeighborEntityDimension = getEntityDimension() >
+      using NeighborEntities =
+         NeighborGridEntityGetter<
+            GridEntity< Meshes::Grid< Dimension, Real, Device, Index >,
+                           0,
                            Config >,
-            NeighbourEntityDimensions >;
+            NeighborEntityDimension >;
 
 
       __cuda_callable__ inline
@@ -363,22 +351,22 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >
       void setBasis( const EntityBasisType& basis ){};
 
  
-      template< int NeighbourEntityDimensions = entityDimensions >
+      template< int NeighborEntityDimension = getEntityDimension() >
       __cuda_callable__ inline
-      const NeighbourEntities< NeighbourEntityDimensions >&
-      getNeighbourEntities() const;
+      const NeighborEntities< NeighborEntityDimension >&
+      getNeighborEntities() const;
  
       __cuda_callable__ inline
       bool isBoundaryEntity() const;
  
       __cuda_callable__ inline
-      VertexType getCenter() const;
+      PointType getCenter() const;
 
       __cuda_callable__ inline
       const RealType getMeasure() const;
  
       __cuda_callable__ inline
-      VertexType getEntityProportions() const;
+      PointType getEntityProportions() const;
  
       __cuda_callable__ inline
       const GridType& getMesh() const;
@@ -391,7 +379,7 @@ class GridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, 0, Config >
  
       CoordinatesType coordinates;
  
-      NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
+      NeighborGridEntitiesStorageType neighborEntitiesStorage;
  
       friend class BoundaryGridEntityChecker< ThisType >;
  
diff --git a/src/TNL/Meshes/GridEntityConfig.h b/src/TNL/Meshes/GridEntityConfig.h
index 89b45f649137d02a78481a3762e15c40c0c6dfd0..a056910a37021c04c383a6673021cb8a072052b6 100644
--- a/src/TNL/Meshes/GridEntityConfig.h
+++ b/src/TNL/Meshes/GridEntityConfig.h
@@ -29,9 +29,9 @@ class GridEntityStencilStorageTag
 };
 
 /****
- * This class says what neighbour grid entity indexes shall be pre-computed and stored in the
- * grid entity structure. If neighbourEntityStorage() returns false, nothing is stored.
- * Otherwise, if neighbour entity storage is enabled, we may store either only neighbour entities in a cross like this
+ * This class says what neighbor grid entity indexes shall be pre-computed and stored in the
+ * grid entity structure. If neighborEntityStorage() returns false, nothing is stored.
+ * Otherwise, if neighbor entity storage is enabled, we may store either only neighbor entities in a cross like this
  *
  *                X
  *   X            X
@@ -39,7 +39,7 @@ class GridEntityStencilStorageTag
  *   X            X
  *                X
  *
- * or all neighbour entities like this
+ * or all neighbor entities like this
  *
  *           XXXXX
  *  XXX      XXXXX
@@ -53,7 +53,7 @@ class GridEntityNoStencilStorage
    public:
  
       template< typename GridEntity >
-      constexpr static bool neighbourEntityStorage( int neighbourEntityStorage )
+      constexpr static bool neighborEntityStorage( int neighborEntityStorage )
       {
          return false;
       }
@@ -70,12 +70,10 @@ class GridEntityCrossStencilStorage
    public:
  
       template< typename GridEntity >
-      constexpr static bool neighbourEntityStorage( const int neighbourEntityDimensions )
+      constexpr static bool neighborEntityStorage( const int neighborEntityDimension )
       {
-         return ( GridEntity::entityDimensions == GridEntity::GridType::meshDimensions &&
-                  neighbourEntityDimensions == GridEntity::GridType::meshDimensions )
-               // FIXME: how is GridEntityCrossStencil cast to int?
-                * GridEntityCrossStencil;
+         return ( GridEntity::getEntityDimension() == GridEntity::GridType::getMeshDimension() &&
+                  neighborEntityDimension == GridEntity::GridType::getMeshDimension() );
       }
  
       constexpr static int getStencilSize()
@@ -86,4 +84,3 @@ class GridEntityCrossStencilStorage
 
 } // namespace Meshes
 } // namespace TNL
-
diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h
index b04c0af49a1d2e30891ee46710bfced1ce69a96f..47060304a5072def2801b54990df03a54c368e24 100644
--- a/src/TNL/Meshes/Mesh.h
+++ b/src/TNL/Meshes/Mesh.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <ostream>
@@ -36,34 +42,34 @@ class Mesh : public Object/*,
       typedef typename MeshTraitsType::CellType                 CellType;
       typedef typename MeshTraitsType::VertexType               VertexType;
       typedef typename MeshTraitsType::PointType                PointType;
-      static const int dimensions = MeshTraitsType::meshDimensions;
-      template< int Dimensions > using EntityTraits = typename MeshTraitsType::template EntityTraits< Dimensions >;
-      template< int Dimensions > using EntityType = typename EntityTraits< Dimensions >::EntityType;
+      static const int dimension = MeshTraitsType::meshDimension;
+      template< int Dimension > using EntityTraits = typename MeshTraitsType::template EntityTraits< Dimension >;
+      template< int Dimension > using EntityType = typename EntityTraits< Dimension >::EntityType;
 
       static String getType();
  
       virtual String getTypeVirtual() const;
  
-      static constexpr int getDimensions();
+      static constexpr int getMeshDimension();
 
-      template< int Dimensions >
+      template< int Dimension >
       bool entitiesAvalable() const;
  
       GlobalIndexType getNumberOfCells() const;
 
       // TODO: rename to getEntitiesCount
-      template< int Dimensions >
+      template< int Dimension >
       GlobalIndexType getNumberOfEntities() const;
 
       CellType& getCell( const GlobalIndexType entityIndex );
 
       const CellType& getCell( const GlobalIndexType entityIndex ) const;
 
-      template< int Dimensions >
-       EntityType< Dimensions >& getEntity( const GlobalIndexType entityIndex );
+      template< int Dimension >
+       EntityType< Dimension >& getEntity( const GlobalIndexType entityIndex );
  
-      template< int Dimensions >
-      const EntityType< Dimensions >& getEntity( const GlobalIndexType entityIndex ) const;
+      template< int Dimension >
+      const EntityType< Dimension >& getEntity( const GlobalIndexType entityIndex ) const;
 
       bool save( File& file ) const;
 
@@ -77,18 +83,18 @@ class Mesh : public Object/*,
       bool operator==( const Mesh& mesh ) const;
 
       // TODO: this is only for mesh intializer - remove it if possible
-      template< typename DimensionsTag >
-           typename EntityTraits< DimensionsTag::value >::StorageArrayType& entitiesArray();
+      template< typename DimensionTag >
+           typename EntityTraits< DimensionTag::value >::StorageArrayType& entitiesArray();
 
  
-      template< typename DimensionsTag, typename SuperDimensionsTag >
+      template< typename DimensionTag, typename SuperDimensionTag >
            typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray();
  
       template< typename EntityTopology, typename SuperdimensionsTag >
       typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionsTag::value >::StorageNetworkType&
       getSuperentityStorageNetwork()
       {
-         return entitiesStorage.template getSuperentityStorageNetwork< SuperdimensionsTag >( MeshDimensionsTag< EntityTopology::dimensions >() );
+         return entitiesStorage.template getSuperentityStorageNetwork< SuperdimensionsTag >( MeshDimensionTag< EntityTopology::dimensions >() );
       }
  
       bool init( const typename MeshTraitsType::PointArrayType& points,
diff --git a/src/TNL/Meshes/MeshBuilder.h b/src/TNL/Meshes/MeshBuilder.h
index d9782c4c28ae53610c4760839ee6e7273964cba9..cfa5058a280edadcfa489b971f9dbbac9e2ada98 100644
--- a/src/TNL/Meshes/MeshBuilder.h
+++ b/src/TNL/Meshes/MeshBuilder.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
@@ -31,7 +37,7 @@ class MeshBuilder
 
    bool setPointsCount( const GlobalIndexType& points )
    {
-      Assert( 0 <= points, std::cerr << "pointsCount = " << points );
+      TNL_ASSERT( 0 <= points, std::cerr << "pointsCount = " << points );
       this->points.setSize( points );
       this->pointsSet.setSize( points );
       pointsSet.setValue( false );
@@ -40,7 +46,7 @@ class MeshBuilder
  
    bool setCellsCount( const GlobalIndexType& cellsCount )
    {
-      Assert( 0 <= cellsCount, std::cerr << "cellsCount = " << cellsCount );
+      TNL_ASSERT( 0 <= cellsCount, std::cerr << "cellsCount = " << cellsCount );
       this->cellSeeds.setSize( cellsCount );
       return true;
    }
@@ -52,7 +58,7 @@ class MeshBuilder
    void setPoint( GlobalIndexType index,
                  const PointType& point )
    {
-	Assert( 0 <= index && index < getPointsCount(), std::cerr << "Index = " << index );
+	TNL_ASSERT( 0 <= index && index < getPointsCount(), std::cerr << "Index = " << index );
 
         this->points[ index ] = point;
         this->pointsSet[ index ] = true;
@@ -60,7 +66,7 @@ class MeshBuilder
 
    CellSeedType& getCellSeed( GlobalIndexType index )
    {
-      Assert( 0 <= index && index < getCellsCount(), std::cerr << "Index = " << index );
+      TNL_ASSERT( 0 <= index && index < getCellsCount(), std::cerr << "Index = " << index );
  
       return this->cellSeeds[ index ];
    }
diff --git a/src/TNL/Meshes/MeshConfigBase.h b/src/TNL/Meshes/MeshConfigBase.h
index 78b047cbab1cebc8f754c211901bb6b8dbe665fa..523afce5b6d84824632eb1b9fd9d01c35ea2ffcb 100644
--- a/src/TNL/Meshes/MeshConfigBase.h
+++ b/src/TNL/Meshes/MeshConfigBase.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
@@ -20,7 +26,7 @@ namespace Meshes {
  * mesh storage layer.
  */
 template< typename Cell,
-          int WorldDimensions = Cell::dimensions,
+          int WorldDimension = Cell::dimensions,
           typename Real = double,
           typename GlobalIndex = int,
           typename LocalIndex = GlobalIndex,
@@ -33,8 +39,8 @@ struct MeshConfigBase
    typedef LocalIndex  LocalIndexType;
    typedef Id          IdType;
 
-   static const int worldDimensions = WorldDimensions;
-   static const int meshDimensions = Cell::dimensions;
+   static const int worldDimension = WorldDimension;
+   static const int meshDimension = Cell::dimensions;
 
    static String getType()
    {
@@ -50,20 +56,20 @@ struct MeshConfigBase
        *  Vertices and cells must always be stored
        */
       return true;
-		//return ( dimensions == 0 || dimensions == cellDimensions );
+		//return ( dimensions == 0 || dimensions == cellDimension );
 	}
  
    /****
     *  Storage of subentities of mesh entities
     */
 	template< typename MeshEntity >
-	static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions )
+	static constexpr bool subentityStorage( MeshEntity, int SubentityDimension )
 	{
       /****
        *  Vertices must always be stored
        */
       return true;
-		//return ( SubentityDimensions == 0 );
+		//return ( SubentityDimension == 0 );
 	}
 
 	/****
@@ -71,22 +77,22 @@ struct MeshConfigBase
     * It must be false for vertices and cells.
     */
 	template< typename MeshEntity >
-	static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions )
+	static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimension )
 	{
-		return ( SubentityDimensions > 0 );
+		return ( SubentityDimension > 0 );
 	}
 
 	/****
     *  Storage of superentities of mesh entities
     */
 	template< typename MeshEntity >
-	static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions )
+	static constexpr bool superentityStorage( MeshEntity, int SuperentityDimension )
 	{
       return true;
 		//return false;
 	}
  
-   static_assert( WorldDimensions >= Cell::dimensions, "The number of the cell dimensions cannot be larger than the world dimension." );
+   static_assert( WorldDimension >= Cell::dimensions, "The number of the cell dimensions cannot be larger than the world dimension." );
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/MeshDetails/CMakeLists.txt b/src/TNL/Meshes/MeshDetails/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Meshes/MeshDetails/MeshEntityId.h b/src/TNL/Meshes/MeshDetails/MeshEntityId.h
index f595042cf92cb95b33756d0bc4d959c75a315433..c514b1b09d86d25998851de8779772d871439766 100644
--- a/src/TNL/Meshes/MeshDetails/MeshEntityId.h
+++ b/src/TNL/Meshes/MeshDetails/MeshEntityId.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
@@ -25,7 +31,7 @@ class MeshEntityId
 
    const IDType &getId() const
    {
-      Assert( this->id >= 0, );
+      TNL_ASSERT( this->id >= 0, );
       return this->id;
    }
 
diff --git a/src/TNL/Meshes/MeshDetails/MeshEntityIntegrityChecker.h b/src/TNL/Meshes/MeshDetails/MeshEntityIntegrityChecker.h
index 3cb41850e52b93f8b290932bd4b3318f0fe363a0..2eabfa69e9e72a2b9e3a96aa4c8a3d11d87eaa19 100644
--- a/src/TNL/Meshes/MeshDetails/MeshEntityIntegrityChecker.h
+++ b/src/TNL/Meshes/MeshDetails/MeshEntityIntegrityChecker.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
diff --git a/src/TNL/Meshes/MeshDetails/MeshEntityOrientation.h b/src/TNL/Meshes/MeshDetails/MeshEntityOrientation.h
index 3d96ec68c643da0a464f470245a08c0521bc9b00..f497c6306015e97aa60a00728e1153770b94ded1 100644
--- a/src/TNL/Meshes/MeshDetails/MeshEntityOrientation.h
+++ b/src/TNL/Meshes/MeshDetails/MeshEntityOrientation.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
diff --git a/src/TNL/Meshes/MeshDetails/MeshEntityReferenceOrientation.h b/src/TNL/Meshes/MeshDetails/MeshEntityReferenceOrientation.h
index 73fb5e80dcb67444423287347f75c0b2d6a44180..bad26901bc0cdbfb1366ea28eecf34103c82e745 100644
--- a/src/TNL/Meshes/MeshDetails/MeshEntityReferenceOrientation.h
+++ b/src/TNL/Meshes/MeshDetails/MeshEntityReferenceOrientation.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
@@ -30,7 +36,7 @@ class MeshEntityReferenceOrientation
          auto referenceCornerIds = referenceSeed.getCornerIds();
          for( LocalIndexType i = 0; i < referenceCornerIds.getSize(); i++ )
          {
-            Assert( this->cornerIdsMap.find( referenceCornerIds[i]) == this->cornerIdsMap.end(), );
+            TNL_ASSERT( this->cornerIdsMap.find( referenceCornerIds[i]) == this->cornerIdsMap.end(), );
             this->cornerIdsMap.insert( std::make_pair( referenceCornerIds[i], i ) );
          }
       }
@@ -43,7 +49,7 @@ class MeshEntityReferenceOrientation
          auto cornerIds = seed.getCornerIds();
          for( LocalIndexType i = 0; i < cornerIds.getSize(); i++ )
          {
-            Assert( this->cornerIdsMap.find( cornerIds[ i ] ) != this->cornerIdsMap.end(), );
+            TNL_ASSERT( this->cornerIdsMap.find( cornerIds[ i ] ) != this->cornerIdsMap.end(), );
             result.setPermutationValue( i, this->cornerIdsMap.find( cornerIds[ i ])->second );
          }
          return result;
diff --git a/src/TNL/Meshes/MeshDetails/MeshEntity_impl.h b/src/TNL/Meshes/MeshDetails/MeshEntity_impl.h
index 65d96194d6811e783e5b154d6fffd9e517b79242..9e9ff9b8aac46c8434d00b55c4b9361bcdcecc4d 100644
--- a/src/TNL/Meshes/MeshDetails/MeshEntity_impl.h
+++ b/src/TNL/Meshes/MeshDetails/MeshEntity_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshEntity.h>
@@ -89,7 +95,7 @@ void
 MeshEntity< MeshConfig, EntityTopology >::
 print( std::ostream& str ) const
 {
-   str << "\t Mesh entity dimensions: " << EntityTopology::dimensions << std::endl;
+   str << "\t Mesh entity dimension: " << EntityTopology::dimensions << std::endl;
    MeshSubentityStorageLayers< MeshConfig, EntityTopology >::print( str );
    MeshSuperentityAccess< MeshConfig, EntityTopology >::print( str );
 }
@@ -110,7 +116,7 @@ template< typename MeshConfig,
           typename EntityTopology >
 constexpr int
 MeshEntity< MeshConfig, EntityTopology >::
-getEntityDimensions() const
+getEntityDimension() const
 {
    return EntityTopology::dimensions;
 }
@@ -146,13 +152,13 @@ MeshEntity< MeshConfig, EntityTopology >::
 getSubentityIndex( const LocalIndexType localIndex) const
 {
    static_assert( SubentityTraits< Subdimensions >::storageEnabled, "You try to get subentity which is not configured for storage." );
-   Assert( 0 <= localIndex &&
+   TNL_ASSERT( 0 <= localIndex &&
               localIndex < SubentityTraits< Subdimensions >::count,
               std::cerr << "localIndex = " << localIndex
                    << " subentitiesCount = "
                    << SubentityTraits< Subdimensions >::count );
    typedef MeshSubentityStorageLayers< MeshConfig, EntityTopology >  SubentityBaseType;
-   return SubentityBaseType::getSubentityIndex( MeshDimensionsTag< Subdimensions >(),
+   return SubentityBaseType::getSubentityIndex( MeshDimensionTag< Subdimensions >(),
                                                 localIndex );
 }
 
@@ -165,7 +171,7 @@ MeshEntity< MeshConfig, EntityTopology >::
 {
    static_assert( SubentityTraits< Subdimensions >::storageEnabled, "You try to get subentities which are not configured for storage." );
    typedef MeshSubentityStorageLayers< MeshConfig, EntityTopology >  SubentityBaseType;
-   return SubentityBaseType::getSubentitiesIndices( MeshDimensionsTag< Subdimensions >() );
+   return SubentityBaseType::getSubentitiesIndices( MeshDimensionTag< Subdimensions >() );
 }
 
 template< typename MeshConfig,
@@ -177,59 +183,59 @@ getSubentitiesIndices() const
 {
    static_assert( SubentityTraits< Subdimensions >::storageEnabled, "You try to set subentities which are not configured for storage." );
    typedef MeshSubentityStorageLayers< MeshConfig, EntityTopology >  SubentityBaseType;
-   return SubentityBaseType::getSubentitiesIndices( MeshDimensionsTag< Subdimensions >() );
+   return SubentityBaseType::getSubentitiesIndices( MeshDimensionTag< Subdimensions >() );
 }
 
 template< typename MeshConfig,
           typename EntityTopology >
-   template< int SuperDimensions >
+   template< int SuperDimension >
 typename MeshEntity< MeshConfig, EntityTopology >::LocalIndexType
 MeshEntity< MeshConfig, EntityTopology >::
 getNumberOfSuperentities() const
 {
-   static_assert( SuperentityTraits< SuperDimensions >::available, "You try to get number of superentities which are not configured for storage." );
+   static_assert( SuperentityTraits< SuperDimension >::available, "You try to get number of superentities which are not configured for storage." );
    typedef MeshSuperentityAccess< MeshConfig, EntityTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getNumberOfSuperentities( MeshDimensionsTag< SuperDimensions >() );
+   return SuperentityBaseType::getNumberOfSuperentities( MeshDimensionTag< SuperDimension >() );
 }
 
 template< typename MeshConfig,
           typename EntityTopology >
-   template< int SuperDimensions >
+   template< int SuperDimension >
 typename MeshEntity< MeshConfig, EntityTopology >::GlobalIndexType
 MeshEntity< MeshConfig, EntityTopology >::
 getSuperentityIndex( const LocalIndexType localIndex ) const
 {
-   static_assert( SuperentityTraits< SuperDimensions >::storageEnabled, "You try to get superentity which is not configured for storage." );
-   Assert( localIndex < this->getNumberOfSuperentities< SuperDimensions >(),
+   static_assert( SuperentityTraits< SuperDimension >::storageEnabled, "You try to get superentity which is not configured for storage." );
+   TNL_ASSERT( localIndex < this->getNumberOfSuperentities< SuperDimension >(),
               std::cerr << " localIndex = " << localIndex
-                   << " this->getNumberOfSuperentities< Dimensions >() = " << this->getNumberOfSuperentities< SuperDimensions >() << std::endl; );
+                   << " this->getNumberOfSuperentities< Dimension >() = " << this->getNumberOfSuperentities< SuperDimension >() << std::endl; );
    typedef MeshSuperentityAccess< MeshConfig, EntityTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getSuperentityIndex( MeshDimensionsTag< SuperDimensions >(),
+   return SuperentityBaseType::getSuperentityIndex( MeshDimensionTag< SuperDimension >(),
                                                     localIndex );
 }
 
 template< typename MeshConfig,
           typename EntityTopology >
-   template< int SuperDimensions >
-typename MeshEntity< MeshConfig, EntityTopology >::template SuperentityTraits< SuperDimensions >::AccessArrayType&
+   template< int SuperDimension >
+typename MeshEntity< MeshConfig, EntityTopology >::template SuperentityTraits< SuperDimension >::AccessArrayType&
 MeshEntity< MeshConfig, EntityTopology >::
 getSuperentitiesIndices()
 {
-   static_assert( SuperentityTraits< SuperDimensions >::storageEnabled, "You try to get superentities which are not configured for storage." );
+   static_assert( SuperentityTraits< SuperDimension >::storageEnabled, "You try to get superentities which are not configured for storage." );
    typedef MeshSuperentityAccess< MeshConfig, EntityTopology >  SuperentityBaseType;
-   //return SuperentityBaseType::getSuperentitiesIndices( MeshDimensionsTag< Dimensions >() );
+   //return SuperentityBaseType::getSuperentitiesIndices( MeshDimensionTag< Dimension >() );
 }
 
 template< typename MeshConfig,
           typename EntityTopology >
-   template< int SuperDimensions >
-const typename MeshEntity< MeshConfig, EntityTopology >::template SuperentityTraits< SuperDimensions >::AccessArrayType&
+   template< int SuperDimension >
+const typename MeshEntity< MeshConfig, EntityTopology >::template SuperentityTraits< SuperDimension >::AccessArrayType&
 MeshEntity< MeshConfig, EntityTopology >::
 getSuperentitiesIndices() const
 {
-   static_assert( SuperentityTraits< SuperDimensions >::storageEnabled, "You try to get superentities which are not configured for storage." );
+   static_assert( SuperentityTraits< SuperDimension >::storageEnabled, "You try to get superentities which are not configured for storage." );
    typedef MeshSuperentityAccess< MeshConfig, EntityTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getSubentitiesIndices( MeshDimensionsTag< SuperDimensions >() );
+   return SuperentityBaseType::getSubentitiesIndices( MeshDimensionTag< SuperDimension >() );
 }
 
 template< typename MeshConfig,
@@ -270,15 +276,15 @@ getVerticesIndices() const
 
 template< typename MeshConfig,
           typename EntityTopology >
-   template< int Dimensions >
+   template< int Dimension >
 typename MeshEntity< MeshConfig, EntityTopology >::IdPermutationArrayAccessorType
 MeshEntity< MeshConfig, EntityTopology >::
 subentityOrientation( LocalIndexType index ) const
 {
-   static const LocalIndexType subentitiesCount = SubentityTraits< Dimensions >::count;
-   Assert( 0 <= index && index < subentitiesCount, );
+   static const LocalIndexType subentitiesCount = SubentityTraits< Dimension >::count;
+   TNL_ASSERT( 0 <= index && index < subentitiesCount, );
 
-   return SubentityStorageLayers::subentityOrientation( MeshDimensionsTag< Dimensions >(), index );
+   return SubentityStorageLayers::subentityOrientation( MeshDimensionTag< Dimension >(), index );
 }
 
 /****
@@ -294,13 +300,13 @@ setSubentityIndex( const LocalIndexType localIndex,
                    const GlobalIndexType globalIndex )
 {
    static_assert( SubentityTraits< Subdimensions >::storageEnabled, "You try to set subentity which is not configured for storage." );
-   Assert( 0 <= localIndex &&
+   TNL_ASSERT( 0 <= localIndex &&
               localIndex < SubentityTraits< Subdimensions >::count,
               std::cerr << "localIndex = " << localIndex
                    << " subentitiesCount = "
                    << SubentityTraits< Subdimensions >::count );
    typedef MeshSubentityStorageLayers< MeshConfig, EntityTopology >  SubentityBaseType;
-   SubentityBaseType::setSubentityIndex( MeshDimensionsTag< Subdimensions >(),
+   SubentityBaseType::setSubentityIndex( MeshDimensionTag< Subdimensions >(),
                                          localIndex,
                                          globalIndex );
 }
@@ -312,7 +318,7 @@ typename MeshEntity< MeshConfig, EntityTopology >::template SubentityTraits< Sub
 MeshEntity< MeshConfig, EntityTopology >::
 subentityIdsArray()
 {
-   return SubentityStorageLayers::subentityIdsArray( MeshDimensionsTag< Subdimensions >() );
+   return SubentityStorageLayers::subentityIdsArray( MeshDimensionTag< Subdimensions >() );
 }
 
 template< typename MeshConfig,
@@ -322,7 +328,7 @@ typename MeshEntity< MeshConfig, EntityTopology >::IdArrayAccessorType&
 MeshEntity< MeshConfig, EntityTopology >::
 superentityIdsArray()
 {
-   return SuperentityAccessBase::superentityIdsArray( MeshDimensionsTag< Superdimensions >());
+   return SuperentityAccessBase::superentityIdsArray( MeshDimensionTag< Superdimensions >());
 }
 
 template< typename MeshConfig,
@@ -332,7 +338,7 @@ typename MeshEntity< MeshConfig, EntityTopology >::template SubentityTraits< Sub
 MeshEntity< MeshConfig, EntityTopology >::
 subentityOrientationsArray()
 {
-   return SubentityStorageLayers::subentityOrientationsArray( MeshDimensionsTag< Subdimensions >() );
+   return SubentityStorageLayers::subentityOrientationsArray( MeshDimensionTag< Subdimensions >() );
 }
 
 /****
@@ -388,7 +394,7 @@ void
 MeshEntity< MeshConfig, MeshVertexTopology >::
 print( std::ostream& str ) const
 {
-   str << "\t Mesh entity dimensions: " << MeshVertexTopology::dimensions << std::endl;
+   str << "\t Mesh entity dimension: " << MeshVertexTopology::dimensions << std::endl;
    str << "\t Coordinates = ( " << point << " )";
    MeshSuperentityAccess< MeshConfig, MeshVertexTopology >::print( str );
 }
@@ -407,7 +413,7 @@ operator==( const MeshEntity& entity ) const
 template< typename MeshConfig >
 constexpr int
 MeshEntity< MeshConfig, MeshVertexTopology >::
-getEntityDimensions() const
+getEntityDimension() const
 {
    return EntityTopology::dimensions;
 }
@@ -419,7 +425,7 @@ MeshEntity< MeshConfig, MeshVertexTopology >::
 getNumberOfSuperentities() const
 {
    typedef MeshSuperentityAccess< MeshConfig, MeshVertexTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getNumberOfSuperentities( MeshDimensionsTag< Superdimensions >() );
+   return SuperentityBaseType::getNumberOfSuperentities( MeshDimensionTag< Superdimensions >() );
 }
 
 template< typename MeshConfig >
@@ -429,7 +435,7 @@ MeshEntity< MeshConfig, MeshVertexTopology >::
 getSuperentitiesIndices()
 {
    typedef MeshSuperentityAccess< MeshConfig, MeshVertexTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getSuperentitiesIndices( MeshDimensionsTag< Superdimensions >() );
+   return SuperentityBaseType::getSuperentitiesIndices( MeshDimensionTag< Superdimensions >() );
 }
 
 template< typename MeshConfig >
@@ -439,20 +445,20 @@ MeshEntity< MeshConfig, MeshVertexTopology >::
 getSuperentitiesIndeces() const
 {
    typedef MeshSuperentityAccess< MeshConfig, MeshVertexTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getSubentitiesIndices( MeshDimensionsTag< Superdimensions >() );
+   return SuperentityBaseType::getSubentitiesIndices( MeshDimensionTag< Superdimensions >() );
 }
 
 template< typename MeshConfig >
-   template< int Dimensions >
+   template< int Dimension >
 typename MeshEntity< MeshConfig, MeshVertexTopology >::GlobalIndexType
 MeshEntity< MeshConfig, MeshVertexTopology >::
 getSuperentityIndex( const LocalIndexType localIndex ) const
 {
-   Assert( localIndex < this->getNumberOfSuperentities< Dimensions >(),
+   TNL_ASSERT( localIndex < this->getNumberOfSuperentities< Dimension >(),
               std::cerr << " localIndex = " << localIndex
-                   << " this->getNumberOfSuperentities< Dimensions >() = " << this->getNumberOfSuperentities< Dimensions >() << std::endl; );
+                   << " this->getNumberOfSuperentities< Dimension >() = " << this->getNumberOfSuperentities< Dimension >() << std::endl; );
    typedef MeshSuperentityAccess< MeshConfig, MeshVertexTopology >  SuperentityBaseType;
-   return SuperentityBaseType::getSuperentityIndex( MeshDimensionsTag< Dimensions >(),
+   return SuperentityBaseType::getSuperentityIndex( MeshDimensionTag< Dimension >(),
                                                     localIndex );
 }
 
@@ -478,7 +484,7 @@ typename MeshEntity< MeshConfig, MeshVertexTopology >::MeshTraitsType::IdArrayAc
 MeshEntity< MeshConfig, MeshVertexTopology >::
 superentityIdsArray()
 {
-   return SuperentityAccessBase::superentityIdsArray( MeshDimensionsTag< Superdimensions >());
+   return SuperentityAccessBase::superentityIdsArray( MeshDimensionTag< Superdimensions >());
 }
 
 template< typename MeshConfig,
diff --git a/src/TNL/Meshes/MeshDetails/MeshIntegrityChecker.h b/src/TNL/Meshes/MeshDetails/MeshIntegrityChecker.h
index 71c0a106835d0dbbf0159ca76aedf781fe346582..42ddaa1d2dded36a364bcdafe3ab66828be45c61 100644
--- a/src/TNL/Meshes/MeshDetails/MeshIntegrityChecker.h
+++ b/src/TNL/Meshes/MeshDetails/MeshIntegrityChecker.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Mesh.h>
@@ -19,10 +25,10 @@ namespace Meshes {
 template< typename MeshType >
 class MeshIntegrityChecker
 : public MeshIntegrityCheckerLayer< MeshType,
-                                       MeshDimensionsTag< MeshType::Config::CellType::dimensions > >
+                                       MeshDimensionTag< MeshType::Config::CellType::dimensions > >
 {
-      typedef MeshDimensionsTag< MeshType::Config::CellType::dimensions > DimensionsTag;
-      typedef MeshIntegrityCheckerLayer< MeshType, DimensionsTag > BaseType;
+      typedef MeshDimensionTag< MeshType::Config::CellType::dimensions > DimensionTag;
+      typedef MeshIntegrityCheckerLayer< MeshType, DimensionTag > BaseType;
 
    public:
       static bool checkMesh( const MeshType& mesh )
diff --git a/src/TNL/Meshes/MeshDetails/MeshIntegrityCheckerLayer.h b/src/TNL/Meshes/MeshDetails/MeshIntegrityCheckerLayer.h
index 8ce8d050a7f7f603aba5260103e5d12da1de4ee4..302ed0b05ad395eb1fdf4d1a26228c49f5bdfbad 100644
--- a/src/TNL/Meshes/MeshDetails/MeshIntegrityCheckerLayer.h
+++ b/src/TNL/Meshes/MeshDetails/MeshIntegrityCheckerLayer.h
@@ -8,32 +8,38 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 
 namespace TNL {
 namespace Meshes {
 
 template< typename MeshType,
-          typename DimensionsTag,
+          typename DimensionTag,
           bool EntityStorageTag = MeshEntityTraits< typename MeshType::Config,
-                                                       DimensionsTag::value >::storageEnabled >
+                                                       DimensionTag::value >::storageEnabled >
 class MeshIntegrityCheckerLayer;
 
 template< typename MeshType,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshIntegrityCheckerLayer< MeshType,
-                                    DimensionsTag,
+                                    DimensionTag,
                                     true >
    : public MeshIntegrityCheckerLayer< MeshType,
-                                          typename DimensionsTag::Decrement >
+                                          typename DimensionTag::Decrement >
 {
    public:
       typedef MeshIntegrityCheckerLayer< MeshType,
-                                            typename DimensionsTag::Decrement >     BaseType;
-      enum { dimensions = DimensionsTag::value };
+                                            typename DimensionTag::Decrement >     BaseType;
+      enum { dimensions = DimensionTag::value };
 
       static bool checkEntities( const MeshType& mesh )
       {
@@ -55,7 +61,7 @@ class MeshIntegrityCheckerLayer< MeshType,
 
 template< typename MeshType >
 class MeshIntegrityCheckerLayer< MeshType,
-                                    MeshDimensionsTag< 0 >,
+                                    MeshDimensionTag< 0 >,
                                     true >
 {
    public:
@@ -79,19 +85,19 @@ class MeshIntegrityCheckerLayer< MeshType,
 };
 
 template< typename MeshType,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshIntegrityCheckerLayer< MeshType,
-                                    DimensionsTag,
+                                    DimensionTag,
                                     false >
    : public MeshIntegrityCheckerLayer< MeshType,
-                                          typename DimensionsTag::Decrement >
+                                          typename DimensionTag::Decrement >
 {
 
 };
 
 template< typename MeshType >
 class MeshIntegrityCheckerLayer< MeshType,
-                                    MeshDimensionsTag< 0 >,
+                                    MeshDimensionTag< 0 >,
                                     false >
 {
 
diff --git a/src/TNL/Meshes/MeshDetails/MeshReaderNetgen.h b/src/TNL/Meshes/MeshDetails/MeshReaderNetgen.h
index 4ca58293bdeaec73512608b60bf3d9e01332df6e..d3264a480aefc1bc82a42ae3affb08f95a73e517 100644
--- a/src/TNL/Meshes/MeshDetails/MeshReaderNetgen.h
+++ b/src/TNL/Meshes/MeshDetails/MeshReaderNetgen.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <fstream>
@@ -225,7 +231,7 @@ class MeshReaderNetgen
        return true;
    }
 
-   int getDimensions() const
+   int getDimension() const
    {
       return this->dimensions;
    }
diff --git a/src/TNL/Meshes/MeshDetails/MeshWriterNetgen.h b/src/TNL/Meshes/MeshDetails/MeshWriterNetgen.h
index 757807734a02438ab1150b48cf3c1ff97ffeffef..82cbc84a24ae2b57bbac34d5b995a6a99befc627 100644
--- a/src/TNL/Meshes/MeshDetails/MeshWriterNetgen.h
+++ b/src/TNL/Meshes/MeshDetails/MeshWriterNetgen.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <fstream>
@@ -37,7 +43,7 @@ class MeshWriterNetgen
       outputFile << std::setprecision( 6 );
       outputFile << fixed;
 
-      const int meshDimensions = MeshType::meshDimensions;
+      const int meshDimension = MeshType::meshDimension;
       typedef typename MeshType::template EntitiesTraits< 0 >::GlobalIndexType VerticesIndexType;
       typedef typename MeshType::PointType                                     PointType;
       const VerticesIndexType numberOfVertices = mesh.getNumberOfVertices();
@@ -46,23 +52,23 @@ class MeshWriterNetgen
       {
          const PointType& point = mesh.getVertex( i ).getPoint();
          outputFile << " ";
-         for( int d = 0; d < meshDimensions; d++ )
+         for( int d = 0; d < meshDimension; d++ )
             outputFile << " " << point[ d ];
          outputFile << std::endl;
       }
 
-      typedef typename MeshType::template EntitiesTraits< meshDimensions >::GlobalIndexType CellIndexType;
-      typedef typename MeshType::template EntitiesTraits< meshDimensions >::Type            CellType;
+      typedef typename MeshType::template EntitiesTraits< meshDimension >::GlobalIndexType CellIndexType;
+      typedef typename MeshType::template EntitiesTraits< meshDimension >::Type            CellType;
       typedef typename CellType::LocalIndexType                                             LocalIndexType;
 
-      const CellIndexType numberOfCells = mesh.template getNumberOfEntities< meshDimensions >();
+      const CellIndexType numberOfCells = mesh.template getNumberOfEntities< meshDimension >();
       outputFile << numberOfCells << std::endl;
       for( CellIndexType cellIdx = 0; cellIdx < numberOfCells; cellIdx++ )
       {
-         const CellType& cell = mesh.template getEntity< meshDimensions >( cellIdx );
+         const CellType& cell = mesh.template getEntity< meshDimension >( cellIdx );
          outputFile << "   1";
          for( LocalIndexType cellVertexIdx = 0;
-              cellVertexIdx < meshDimensions + 1;
+              cellVertexIdx < meshDimension + 1;
               cellVertexIdx++ )
             outputFile << " " << cell.getVertexIndex( cellVertexIdx );
          outputFile << std::endl;
diff --git a/src/TNL/Meshes/MeshDetails/MeshWriterVTKLegacy.h b/src/TNL/Meshes/MeshDetails/MeshWriterVTKLegacy.h
index ff4673a790ebfd08ecf33c93916be5b3990a5f7d..930e00e5ba977111f3b9f4adf30a00d7d2a62003 100644
--- a/src/TNL/Meshes/MeshDetails/MeshWriterVTKLegacy.h
+++ b/src/TNL/Meshes/MeshDetails/MeshWriterVTKLegacy.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <fstream>
diff --git a/src/TNL/Meshes/MeshDetails/Mesh_impl.h b/src/TNL/Meshes/MeshDetails/Mesh_impl.h
index cff4831ee7b50424de181f1a2d38edd07801aeaf..eb5f457a6b4449832e750ac96eecba033e173ded 100644
--- a/src/TNL/Meshes/MeshDetails/Mesh_impl.h
+++ b/src/TNL/Meshes/MeshDetails/Mesh_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Mesh.h>
@@ -34,27 +40,27 @@ getTypeVirtual() const
 template< typename MeshConfig >
 constexpr int
 Mesh< MeshConfig >::
-getDimensions()
+getMeshDimension()
 {
-   return dimensions;
+   return dimension;
 }
 
 template< typename MeshConfig >
-   template< int Dimensions >
+   template< int Dimension >
 bool
 Mesh< MeshConfig >::
 entitiesAvalable() const
 {
-   return MeshTraitsType::template EntityTraits< Dimensions >::available;
+   return MeshTraitsType::template EntityTraits< Dimension >::available;
 }
 
 template< typename MeshConfig >
-   template< int Dimensions >
+   template< int Dimension >
 typename Mesh< MeshConfig >::GlobalIndexType
 Mesh< MeshConfig >::
 getNumberOfEntities() const
 {
-   return entitiesStorage.getNumberOfEntities( MeshDimensionsTag< Dimensions >() );
+   return entitiesStorage.getNumberOfEntities( MeshDimensionTag< Dimension >() );
 }
 
 template< typename MeshConfig >
@@ -62,7 +68,7 @@ typename Mesh< MeshConfig >::GlobalIndexType
 Mesh< MeshConfig >::
 template getNumberOfCells() const
 {
-   return entitiesStorage.getNumberOfEntities( MeshDimensionsTag< dimensions >() );
+   return entitiesStorage.getNumberOfEntities( MeshDimensionTag< dimensions >() );
 }
 
 template< typename MeshConfig >
@@ -70,7 +76,7 @@ typename Mesh< MeshConfig >::CellType&
 Mesh< MeshConfig >::
 getCell( const GlobalIndexType cellIndex )
 {
-   return entitiesStorage.getEntity( MeshDimensionsTag< dimensions >(), cellIndex );
+   return entitiesStorage.getEntity( MeshDimensionTag< dimensions >(), cellIndex );
 }
 
 template< typename MeshConfig >
@@ -78,25 +84,25 @@ const typename Mesh< MeshConfig >::CellType&
 Mesh< MeshConfig >::
 getCell( const GlobalIndexType cellIndex ) const
 {
-   return entitiesStorage.getEntity( MeshDimensionsTag< dimensions >(), cellIndex );
+   return entitiesStorage.getEntity( MeshDimensionTag< dimensions >(), cellIndex );
 }
 
 template< typename MeshConfig >
-   template< int Dimensions >
-typename Mesh< MeshConfig >::template EntityType< Dimensions >&
+   template< int Dimension >
+typename Mesh< MeshConfig >::template EntityType< Dimension >&
 Mesh< MeshConfig >::
 getEntity( const GlobalIndexType entityIndex )
 {
-   return entitiesStorage.getEntity( MeshDimensionsTag< Dimensions >(), entityIndex );
+   return entitiesStorage.getEntity( MeshDimensionTag< Dimension >(), entityIndex );
 }
 
 template< typename MeshConfig >
-   template< int Dimensions >
-const typename Mesh< MeshConfig >::template EntityType< Dimensions >&
+   template< int Dimension >
+const typename Mesh< MeshConfig >::template EntityType< Dimension >&
 Mesh< MeshConfig >::
 getEntity( const GlobalIndexType entityIndex ) const
 {
-   return entitiesStorage.getEntity( MeshDimensionsTag< Dimensions >(), entityIndex );
+   return entitiesStorage.getEntity( MeshDimensionTag< Dimension >(), entityIndex );
 }
  
 template< typename MeshConfig >
@@ -144,21 +150,21 @@ operator==( const Mesh& mesh ) const
 }
 
 template< typename MeshConfig >
-   template< typename DimensionsTag >
-typename Mesh< MeshConfig >::template EntityTraits< DimensionsTag::value >::StorageArrayType&
+   template< typename DimensionTag >
+typename Mesh< MeshConfig >::template EntityTraits< DimensionTag::value >::StorageArrayType&
 Mesh< MeshConfig >::
 entitiesArray()
 {
-   return entitiesStorage.entitiesArray( DimensionsTag() );
+   return entitiesStorage.entitiesArray( DimensionTag() );
 }
 
 template< typename MeshConfig >
-   template< typename DimensionsTag, typename SuperDimensionsTag >
+   template< typename DimensionTag, typename SuperDimensionTag >
 typename Mesh< MeshConfig >::MeshTraitsType::GlobalIdArrayType&
 Mesh< MeshConfig >::
 superentityIdsArray()
 {
-   return entitiesStorage.template superentityIdsArray< SuperDimensionsTag >( DimensionsTag() );
+   return entitiesStorage.template superentityIdsArray< SuperDimensionTag >( DimensionTag() );
 }
 
 template< typename MeshConfig >
diff --git a/src/TNL/Meshes/MeshDetails/config/CMakeLists.txt b/src/TNL/Meshes/MeshDetails/config/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Meshes/MeshDetails/config/MeshConfigValidator.h b/src/TNL/Meshes/MeshDetails/config/MeshConfigValidator.h
index d4556a0999339e939de01dacb97364265d461ee0..ba079790e1d18079e881b4b19af4935fa68df1b6 100644
--- a/src/TNL/Meshes/MeshDetails/config/MeshConfigValidator.h
+++ b/src/TNL/Meshes/MeshDetails/config/MeshConfigValidator.h
@@ -8,11 +8,17 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Assert.h>
 #include <TNL/Meshes/Topologies/MeshEntityTopology.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 
 namespace TNL {
 namespace Meshes {
@@ -33,7 +39,7 @@ public MeshConfigValidatorSubtopologyLayer< MeshConfig, MeshEntity, typename dim
 
 template< typename MeshConfig,
           typename MeshEntity >
-class MeshConfigValidatorSubtopologyLayer< MeshConfig, MeshEntity, MeshDimensionsTag< 0 > >
+class MeshConfigValidatorSubtopologyLayer< MeshConfig, MeshEntity, MeshDimensionTag< 0 > >
 {
    static_assert( ! MeshConfig::subentityStorage( MeshEntity(), 0 ) ||
                     MeshConfig::entityStorage( 0 ), "entities that are stored as subentities must be stored" );
@@ -55,7 +61,7 @@ public MeshConfigValidatorSupertopologyLayer< MeshConfig, MeshEntity, typename d
 
 template< typename MeshConfig,
           typename MeshEntity >
-class MeshConfigValidatorSupertopologyLayer< MeshConfig, MeshEntity, MeshDimensionsTag< MeshEntity::dimensions > >
+class MeshConfigValidatorSupertopologyLayer< MeshConfig, MeshEntity, MeshDimensionTag< MeshEntity::dimensions > >
 {};
 
 
@@ -64,10 +70,10 @@ class MeshConfigValidatorLayer :
  public MeshConfigValidatorLayer< MeshConfig, dimensions - 1 >,
  public MeshConfigValidatorSubtopologyLayer< MeshConfig,
                                                 typename MeshSubtopology< typename MeshConfig::CellTopology, dimensions >::Topology,
-                                                MeshDimensionsTag< dimensions - 1 > >,
+                                                MeshDimensionTag< dimensions - 1 > >,
  public MeshConfigValidatorSupertopologyLayer< MeshConfig,
                                                   typename MeshSubtopology< typename MeshConfig::CellTopology, dimensions >::Topology,
-                                                  MeshDimensionsTag< MeshConfig::CellTopology::dimensions > >
+                                                  MeshDimensionTag< MeshConfig::CellTopology::dimensions > >
 {
 	typedef typename MeshSubtopology< typename MeshConfig::CellTopology, dimensions >::Topology Topology;
 
@@ -84,7 +90,7 @@ class MeshConfigValidatorLayerCell :
    public MeshConfigValidatorLayer< MeshConfig, MeshConfig::CellTopology::dimensions - 1 >,
    public MeshConfigValidatorSubtopologyLayer< MeshConfig,
                                                   typename MeshConfig::CellTopology,
-                                                  MeshDimensionsTag< MeshConfig::CellTopology::dimensions - 1 > >
+                                                  MeshDimensionTag< MeshConfig::CellTopology::dimensions - 1 > >
 {
 	typedef typename MeshConfig::CellTopology    CellTopology;
  	static const int dimensions =  CellTopology::dimensions;
@@ -95,13 +101,13 @@ class MeshConfigValidatorLayerCell :
 template<typename MeshConfig >
 class MeshConfigValidator : public MeshConfigValidatorLayerCell< MeshConfig >
 {
-	static const int meshDimensions = MeshConfig::CellTopology::dimensions;
+	static const int meshDimension = MeshConfig::CellTopology::dimensions;
 
-	static_assert(1 <= meshDimensions, "zero dimensional meshes are not supported");
-	static_assert( meshDimensions <= MeshConfig::worldDimensions, "world dimension must not be less than mesh dimension");
+	static_assert(1 <= meshDimension, "zero dimensional meshes are not supported");
+	static_assert( meshDimension <= MeshConfig::worldDimension, "world dimension must not be less than mesh dimension");
 
 	static_assert( MeshConfig::entityStorage( 0 ), "mesh vertices must be stored");
-	static_assert( MeshConfig::entityStorage( meshDimensions ), "mesh cells must be stored");
+	static_assert( MeshConfig::entityStorage( meshDimension ), "mesh cells must be stored");
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshEntityInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/MeshEntityInitializer.h
index 37e0988199855dce3208b97fb6cbb1f22ec027fe..162ff643063852e9315236fc2ab3ecbe545cd091 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshEntityInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshEntityInitializer.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/StaticFor.h>
@@ -24,11 +30,11 @@ class MeshInitializer;
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag,
-          bool SubentityStorage = MeshSubentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >::storageEnabled,
-          bool SubentityOrientationStorage = MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag::value >::orientationEnabled,
+          typename DimensionTag,
+          bool SubentityStorage = MeshSubentityTraits< MeshConfig, EntityTopology, DimensionTag::value >::storageEnabled,
+          bool SubentityOrientationStorage = MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag::value >::orientationEnabled,
           bool SuperentityStorage = MeshSuperentityTraits< MeshConfig,
-                                                              typename MeshSubentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >::SubentityTopology,
+                                                              typename MeshSubentityTraits< MeshConfig, EntityTopology, DimensionTag::value >::SubentityTopology,
                                                               EntityTopology::dimensions >::storageEnabled >
 class MeshEntityInitializerLayer;
 
@@ -37,30 +43,30 @@ template< typename MeshConfig,
 class MeshEntityInitializer
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           MeshDimensionsTag< EntityTopology::dimensions - 1 > >
+                                           MeshDimensionTag< EntityTopology::dimensions - 1 > >
 {
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                 DimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                 DimensionTag;
    private:
 
       typedef MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           MeshDimensionsTag< EntityTopology::dimensions - 1 > > BaseType;
+                                           MeshDimensionTag< EntityTopology::dimensions - 1 > > BaseType;
  
    typedef
       MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     MeshDimensionsTag< EntityTopology::dimensions - 1 > >   SubentityBaseType;
+                                     MeshDimensionTag< EntityTopology::dimensions - 1 > >   SubentityBaseType;
    typedef
       MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           EntityTopology,
                                           typename
-                                          MeshTraits< MeshConfig >::DimensionsTag > SuperentityBaseType;
+                                          MeshTraits< MeshConfig >::DimensionTag > SuperentityBaseType;
 
-   static const int Dimensions = DimensionsTag::value;
+   static const int Dimension = DimensionTag::value;
    typedef MeshTraits< MeshConfig >                                                 MeshTraitsType;
    typedef typename MeshTraitsType::GlobalIndexType                                 GlobalIndexType;
    typedef typename MeshTraitsType::LocalIndexType                                  LocalIndexType;
-   typedef typename MeshTraitsType::template EntityTraits< Dimensions >             EntityTraitsType;
+   typedef typename MeshTraitsType::template EntityTraits< Dimension >             EntityTraitsType;
  
    typedef typename EntityTraitsType::EntityType                                    EntityType;
    typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, 0 >   SubvertexTraits;
@@ -130,34 +136,34 @@ class MeshEntityInitializer< MeshConfig, MeshVertexTopology >
  */
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      true,
                                      false,
                                      true >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {
    typedef MeshEntityInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >                BaseType;
+                                          typename DimensionTag::Decrement >                BaseType;
 
-   static const int Dimensions = DimensionsTag::value;
+   static const int Dimension = DimensionTag::value;
    typedef MeshTraits< MeshConfig >                                                          MeshTraitsType;
-   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimensions >   SubentityTraitsType;
+   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimension >   SubentityTraitsType;
    typedef typename SubentityTraitsType::SubentityContainerType                              SubentityContainerType;
    typedef typename SubentityTraitsType::AccessArrayType                                     SharedContainerType;
    typedef typename SharedContainerType::ElementType                                         GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                                                     InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >                               EntityInitializerType;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                    EntityDimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                    EntityDimensionTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                                          EntityType;
    typedef MeshEntitySeed< MeshConfig, EntityTopology >                                      SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >            SubentitySeedsCreatorType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >            SubentitySeedsCreatorType;
    typedef typename SubentityTraitsType::IdArrayType                                         IdArrayType;
    typedef typename MeshTraitsType::LocalIndexType                                           LocalIndexType;
 
@@ -165,17 +171,17 @@ class MeshEntityInitializerLayer< MeshConfig,
    static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                 InitializerType& meshInitializer )
    {
-      //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+      //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
       auto subentitySeeds = SubentitySeedsCreatorType::create( entitySeed );
 
-      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >( entity );
+      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >( entity );
       for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
       {
          //cout << "    Adding subentity " << subentityIdsArray[ i ] << std::endl;
          subentityIdsArray[ i ] = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
          meshInitializer.
-            template getSuperentityInitializer< DimensionsTag >().
-               addSuperentity( EntityDimensionsTag(), subentityIdsArray[ i ], entityIndex );
+            template getSuperentityInitializer< DimensionTag >().
+               addSuperentity( EntityDimensionTag(), subentityIdsArray[ i ], entityIndex );
       }
       BaseType::initSubentities( entity, entityIndex, entitySeed, meshInitializer );
    }
@@ -189,33 +195,33 @@ class MeshEntityInitializerLayer< MeshConfig,
  */
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      true,
                                      true,
                                      true >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {
    typedef MeshEntityInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >                   BaseType;
+                                          typename DimensionTag::Decrement >                   BaseType;
 
-   typedef MeshSubentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >                     SubentitiesTraits;
+   typedef MeshSubentityTraits< MeshConfig, EntityTopology, DimensionTag::value >                     SubentitiesTraits;
    typedef typename SubentitiesTraits::SubentityContainerType                                  SubentityContainerType;
    typedef typename SubentitiesTraits::AccessArrayType                                     SharedContainerType;
    typedef typename SharedContainerType::ElementType                                           GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                                                          InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >                                         EntityInitializerType;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                                EntityDimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                                EntityDimensionTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
    typedef MeshEntitySeed< MeshConfig, EntityTopology >                                                SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                      SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag::value >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                      SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag::value >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
    typedef typename SubentitiesTraits::OrientationArrayType                                    OrientationArrayType;
 
@@ -223,21 +229,21 @@ class MeshEntityInitializerLayer< MeshConfig,
    static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                 InitializerType& meshInitializer )
    {
-      //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+      //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
       auto subentitySeeds = SubentitySeedsCreatorType::create( entitySeed );
 
-      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >( entity );
-      OrientationArrayType &subentityOrientationsArray = InitializerType::template subentityOrientationsArray< DimensionsTag >( entity );
+      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >( entity );
+      OrientationArrayType &subentityOrientationsArray = InitializerType::template subentityOrientationsArray< DimensionTag >( entity );
       for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
       {
          //cout << "    Adding subentity " << subentityIdsArray[ i ] << std::endl;
          GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
          subentityIdsArray[ i ] = subentityIndex;
-         subentityOrientationsArray[ i ] = meshInitializer.template getReferenceOrientation< DimensionsTag >( subentityIndex ).createOrientation( subentitySeeds[ i ] );
+         subentityOrientationsArray[ i ] = meshInitializer.template getReferenceOrientation< DimensionTag >( subentityIndex ).createOrientation( subentitySeeds[ i ] );
          //cout << "    Subentity orientation = " << subentityOrientationsArray[ i ].getSubvertexPermutation() << std::endl;
          meshInitializer.
-            template getSuperentityInitializer< DimensionsTag >().
-               addSuperentity( EntityDimensionsTag(), subentityIdsArray[ i ], entityIndex );
+            template getSuperentityInitializer< DimensionTag >().
+               addSuperentity( EntityDimensionTag(), subentityIdsArray[ i ], entityIndex );
       }
  
       BaseType::initSubentities( entity, entityIndex, entitySeed, meshInitializer );
@@ -252,33 +258,33 @@ class MeshEntityInitializerLayer< MeshConfig,
  */
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      true,
                                      true,
                                      false >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {
    typedef MeshEntityInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >                   BaseType;
+                                          typename DimensionTag::Decrement >                   BaseType;
 
-   typedef MeshSubentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >                     SubentitiesTraits;
+   typedef MeshSubentityTraits< MeshConfig, EntityTopology, DimensionTag::value >                     SubentitiesTraits;
    typedef typename SubentitiesTraits::SubentityContainerType                                  SubentityContainerType;
    typedef typename SubentitiesTraits::SharedContainerType                                     SharedContainerType;
    typedef typename SharedContainerType::ElementType                                           GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                                                          InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >                                         EntityInitializerType;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                                EntityDimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                                EntityDimensionTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
    typedef MeshEntitySeed< MeshConfig, EntityTopology >                                                SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                      SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                      SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
    typedef typename SubentitiesTraits::OrientationArrayType                                    OrientationArrayType;
 
@@ -286,16 +292,16 @@ class MeshEntityInitializerLayer< MeshConfig,
    static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                 InitializerType& meshInitializer )
    {
-      //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+      //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
       auto subentitySeeds = SubentitySeedsCreatorType::create( entitySeed );
 
-      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >( entity );
-      OrientationArrayType &subentityOrientationsArray = InitializerType::template subentityOrientationsArray< DimensionsTag >( entity );
+      IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >( entity );
+      OrientationArrayType &subentityOrientationsArray = InitializerType::template subentityOrientationsArray< DimensionTag >( entity );
       for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++ )
       {
          //cout << "    Adding subentity " << subentityIdsArray[ i ] << std::endl;
          subentityIdsArray[ i ] = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
-         subentityOrientationsArray[ i ] = meshInitializer.template getReferenceOrientation< DimensionsTag >( subentitySeeds[ i ] ).createOrientation( subentitySeeds[ i ] );
+         subentityOrientationsArray[ i ] = meshInitializer.template getReferenceOrientation< DimensionTag >( subentitySeeds[ i ] ).createOrientation( subentitySeeds[ i ] );
       }
       BaseType::initSubentities( entity, entityIndex, entitySeed, meshInitializer );
    }
@@ -304,45 +310,45 @@ class MeshEntityInitializerLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      true,
                                      false,
                                      false >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {
    typedef MeshEntityInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >                   BaseType;
+                                          typename DimensionTag::Decrement >                   BaseType;
 
    typedef typename MeshSubentityTraits< MeshConfig,
                                               EntityTopology,
-                                              DimensionsTag::value >::SubentityContainerType          SubentityContainerType;
+                                              DimensionTag::value >::SubentityContainerType          SubentityContainerType;
    typedef typename MeshSubentityTraits< MeshConfig,
                                               EntityTopology,
-                                              DimensionsTag::value >::SharedContainerType             SharedContainerType;
+                                              DimensionTag::value >::SharedContainerType             SharedContainerType;
    typedef typename SharedContainerType::ElementType                                           GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                                                     InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >                                    EntityInitializerType;
    typedef MeshEntity< MeshConfig, EntityTopology >                                               EntityType;
    typedef MeshEntitySeed< MeshConfig, EntityTopology >                                           SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                 SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                 SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
 
    protected:
    static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                 InitializerType& meshInitializer )
    {
-      //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+      //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
       auto subentitySeeds = SubentitySeedsCreatorType::create( entitySeed );
 
-		IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >( entity );
+		IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >( entity );
 		for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++)
 			subentityIdsArray[ i ] = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
 
@@ -352,36 +358,36 @@ class MeshEntityInitializerLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      false,
                                      false,
                                      true >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {
    typedef MeshEntityInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >                BaseType;
+                                          typename DimensionTag::Decrement >                BaseType;
 
    typedef typename MeshSubentityTraits< MeshConfig,
                                               EntityTopology,
-                                              DimensionsTag::value >::SubentityContainerType        SubentityContainerType;
+                                              DimensionTag::value >::SubentityContainerType        SubentityContainerType;
    typedef typename MeshSubentityTraits< MeshConfig,
                                               EntityTopology,
-                                              DimensionsTag::value >::SharedContainerType           SharedContainerType;
+                                              DimensionTag::value >::SharedContainerType           SharedContainerType;
    typedef typename SharedContainerType::DataType                                            GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                                                   InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >                                  EntityInitializerType;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                      EntityDimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                      EntityDimensionTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                                           EntityType;
    typedef MeshEntitySeed< MeshConfig, EntityTopology >                                           SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                 SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                 SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
 
 
@@ -390,15 +396,15 @@ class MeshEntityInitializerLayer< MeshConfig,
       static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                    InitializerType& meshInitializer )
       {
-         //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
          auto subentitySeeds = SubentitySeedsCreatorType::create( entitySeed );
-         IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >( entity );
+         IdArrayType& subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >( entity );
          for( LocalIndexType i = 0; i < subentitySeeds.getSize(); i++)
          {
             GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( subentitySeeds[ i ] );
             meshInitializer.
-               template getSuperentityInitializer< DimensionsTag >().
-                  addSuperentity( EntityDimensionsTag(), subentityIndex, entityIndex );
+               template getSuperentityInitializer< DimensionTag >().
+                  addSuperentity( EntityDimensionTag(), subentityIndex, entityIndex );
          }
          BaseType::initSubentities( entity, entityIndex, entitySeed, meshInitializer );
       }
@@ -406,42 +412,42 @@ class MeshEntityInitializerLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag,
+                                     DimensionTag,
                                      false,
                                      false,
                                      false >
    : public MeshEntityInitializerLayer< MeshConfig,
                                            EntityTopology,
-                                           typename DimensionsTag::Decrement >
+                                           typename DimensionTag::Decrement >
 {};
 
 template< typename MeshConfig,
           typename EntityTopology >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     MeshDimensionsTag< 0 >,
+                                     MeshDimensionTag< 0 >,
                                      true,
                                      false,
                                      true >
 {
-   typedef MeshDimensionsTag< 0 >                                  DimensionsTag;
+   typedef MeshDimensionTag< 0 >                                  DimensionTag;
    typedef MeshSubentityTraits< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag::value >                 SubentitiesTraits;
+                                     DimensionTag::value >                 SubentitiesTraits;
 
    typedef typename SubentitiesTraits::AccessArrayType           SharedContainerType;
    typedef typename SharedContainerType::ElementType                 GlobalIndexType;
 
    typedef MeshInitializer< MeshConfig >                           InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology >          EntityInitializerType;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >              EntityDimensionsTag;
+   typedef MeshDimensionTag< EntityTopology::dimensions >              EntityDimensionTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
       typedef MeshEntitySeed< MeshConfig, EntityTopology >                                           SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                 SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag::value >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                 SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag::value >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
 
 
@@ -450,10 +456,10 @@ class MeshEntityInitializerLayer< MeshConfig,
       static void initSubentities( EntityType& entity, GlobalIndexType entityIndex, const SeedType& entitySeed,
                                    InitializerType& meshInitializer )
       {
-         //cout << "   Initiating subentities with " << DimensionsTag::value << " dimensions ... " << std::endl;
-		   const IdArrayType &subentityIdsArray = InitializerType::template subentityIdsArray< DimensionsTag >(entity);
+         //cout << "   Initiating subentities with " << DimensionTag::value << " dimensions ... " << std::endl;
+		   const IdArrayType &subentityIdsArray = InitializerType::template subentityIdsArray< DimensionTag >(entity);
 		   for( LocalIndexType i = 0; i < subentityIdsArray.getSize(); i++ )
-			   meshInitializer.template getSuperentityInitializer< DimensionsTag >().addSuperentity( EntityDimensionsTag(), subentityIdsArray[ i ], entityIndex);
+			   meshInitializer.template getSuperentityInitializer< DimensionTag >().addSuperentity( EntityDimensionTag(), subentityIdsArray[ i ], entityIndex);
 	}
 
 };
@@ -462,7 +468,7 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     MeshDimensionsTag< 0 >,
+                                     MeshDimensionTag< 0 >,
                                      true,
                                      false,
                                      false >
@@ -470,16 +476,16 @@ class MeshEntityInitializerLayer< MeshConfig,
    typedef MeshInitializer< MeshConfig >         InitializerType;
    typedef MeshEntityInitializer< MeshConfig,
                                      EntityTopology >   EntityInitializerType;
-   typedef MeshDimensionsTag< 0 >                   DimensionsTag;
+   typedef MeshDimensionTag< 0 >                   DimensionTag;
    typedef MeshSubentityTraits< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag::value >                 SubentitiesTraits;
+                                     DimensionTag::value >                 SubentitiesTraits;
    typedef typename SubentitiesTraits::SharedContainerType           SharedContainerType;
    typedef typename SharedContainerType::ElementType                 GlobalIndexType;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
       typedef MeshEntitySeed< MeshConfig, EntityTopology >                                           SeedType;
-   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionsTag >                 SubentitySeedsCreatorType;
-   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag >::IdArrayType IdArrayType;
+   typedef MeshSubentitySeedsCreator< MeshConfig, EntityTopology, DimensionTag >                 SubentitySeedsCreatorType;
+   typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag >::IdArrayType IdArrayType;
    typedef typename MeshTraits< MeshConfig >::LocalIndexType                                             LocalIndexType;
 
 
@@ -495,17 +501,17 @@ template< typename MeshConfig,
           bool SuperEntityStorage >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     MeshDimensionsTag< 0 >,
+                                     MeshDimensionTag< 0 >,
                                      false,
                                      true,
                                      SuperEntityStorage > // Forces termination of recursive inheritance (prevents compiler from generating huge error logs)
 {
    typedef MeshInitializer< MeshConfig >                  InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType;
-   typedef MeshDimensionsTag< 0 >                   DimensionsTag;
+   typedef MeshDimensionTag< 0 >                   DimensionTag;
    typedef MeshSubentityTraits< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag::value >                 SubentitiesTraits;
+                                     DimensionTag::value >                 SubentitiesTraits;
    typedef typename SubentitiesTraits::SharedContainerType           SharedContainerType;
    typedef typename SharedContainerType::ElementType                 GlobalIndexType;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
@@ -519,17 +525,17 @@ template< typename MeshConfig,
           bool SuperEntityStorage >
 class MeshEntityInitializerLayer< MeshConfig,
                                      EntityTopology,
-                                     MeshDimensionsTag< 0 >,
+                                     MeshDimensionTag< 0 >,
                                      false,
                                      false,
                                      SuperEntityStorage > // Forces termination of recursive inheritance (prevents compiler from generating huge error logs)
 {
    typedef MeshInitializer< MeshConfig >                  InitializerType;
    typedef MeshEntityInitializer< MeshConfig, EntityTopology > EntityInitializerType;
-   typedef MeshDimensionsTag< 0 >                   DimensionsTag;
+   typedef MeshDimensionTag< 0 >                   DimensionTag;
    typedef MeshSubentityTraits< MeshConfig,
                                      EntityTopology,
-                                     DimensionsTag::value >                 SubentitiesTraits;
+                                     DimensionTag::value >                 SubentitiesTraits;
    typedef typename SubentitiesTraits::SharedContainerType           SharedContainerType;
    typedef typename SharedContainerType::ElementType                 GlobalIndexType;
    typedef MeshEntity< MeshConfig, EntityTopology >                                                    EntityType;
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeed.h b/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeed.h
index bdb685de379a249e43838146c5c34b7486f2803e..a0f7e561bfead6e1602d3ca754ece09475b29faf 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeed.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeed.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
@@ -37,8 +43,8 @@ class MeshEntitySeed
 
       void setCornerId( LocalIndexType cornerIndex, GlobalIndexType pointIndex )
       {
-         Assert( 0 <= cornerIndex && cornerIndex < getCornersCount(), std::cerr << "cornerIndex = " << cornerIndex );
-         Assert( 0 <= pointIndex, std::cerr << "pointIndex = " << pointIndex );
+         TNL_ASSERT( 0 <= cornerIndex && cornerIndex < getCornersCount(), std::cerr << "cornerIndex = " << cornerIndex );
+         TNL_ASSERT( 0 <= pointIndex, std::cerr << "pointIndex = " << pointIndex );
 
          this->cornerIds[ cornerIndex ] = pointIndex;
       }
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeedKey.h b/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeedKey.h
index f3326bf319fdce2adddd0fec9541b3ac7e5fa332..32ecff1df3b89d6db6c6f96b22aefa3e67f046c2 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeedKey.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshEntitySeedKey.h
@@ -8,9 +8,15 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 
 namespace TNL {
 namespace Meshes {
@@ -21,7 +27,7 @@ class MeshEntitySeed;
 
 template< typename MeshConfig,
           typename EntityTopology,
-          int Dimensions >
+          int Dimension >
 class MeshSubentityTraits;
 
 /****
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
index 22e88efda6d845112e217c93eb53045790330d38..e690d35918246db0e51c7206d9a2d90ae2739a6c 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshInitializer.h
@@ -8,9 +8,15 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
@@ -28,11 +34,11 @@ template< typename MeshConfig >
 class Mesh;
 
 template< typename MeshConfig,
-          typename DimensionsTag,
+          typename DimensionTag,
           bool EntityStorage =
-             MeshEntityTraits< MeshConfig, DimensionsTag::value >::storageEnabled,
+             MeshEntityTraits< MeshConfig, DimensionTag::value >::storageEnabled,
           bool EntityReferenceOrientationStorage =
-             MeshTraits< MeshConfig >::template EntityTraits< DimensionsTag::value >::orientationNeeded >
+             MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::orientationNeeded >
 class MeshInitializerLayer;
 
 
@@ -43,22 +49,22 @@ class MeshEntityInitializer;
 template< typename MeshConfig >
 class MeshInitializer
    : public MeshInitializerLayer< MeshConfig,
-                                     typename MeshTraits< MeshConfig >::DimensionsTag >
+                                     typename MeshTraits< MeshConfig >::DimensionTag >
 {
    public:
  
       typedef Mesh< MeshConfig >                                  MeshType;
       typedef MeshTraits< MeshConfig >                            MeshTraitsType;
-      static const int Dimensions = MeshTraitsType::meshDimensions;
-      typedef MeshDimensionsTag< Dimensions >                      DimensionsTag;
-      typedef MeshInitializerLayer< MeshConfig, DimensionsTag >   BaseType;
+      static const int Dimension = MeshTraitsType::meshDimension;
+      typedef MeshDimensionTag< Dimension >                      DimensionTag;
+      typedef MeshInitializerLayer< MeshConfig, DimensionTag >   BaseType;
       typedef typename MeshTraitsType::PointArrayType             PointArrayType;
       typedef typename MeshTraitsType::CellSeedArrayType          CellSeedArrayType;
       typedef typename MeshTraitsType::GlobalIndexType            GlobalIndexType;
  
-      template< typename DimensionsTag, typename SuperdimensionsTag > using SuperentityStorageNetwork =
+      template< typename DimensionTag, typename SuperdimensionsTag > using SuperentityStorageNetwork =
       typename MeshTraitsType::template SuperentityTraits<
-         typename MeshTraitsType::template EntityTraits< DimensionsTag::value >::EntityTopology,
+         typename MeshTraitsType::template EntityTraits< DimensionTag::value >::EntityTopology,
          SuperdimensionsTag::value >::StorageNetworkType;
 
 
@@ -90,39 +96,39 @@ class MeshInitializer
          return true;
       }
 
-      template<typename SubDimensionsTag, typename EntityType >
-      static typename MeshTraitsType::template SubentityTraits< typename EntityType::EntityTopology, SubDimensionsTag::value >::IdArrayType&
+      template<typename SubDimensionTag, typename EntityType >
+      static typename MeshTraitsType::template SubentityTraits< typename EntityType::EntityTopology, SubDimensionTag::value >::IdArrayType&
       subentityIdsArray( EntityType& entity )
       {
-         return entity.template subentityIdsArray< SubDimensionsTag::value >();
+         return entity.template subentityIdsArray< SubDimensionTag::value >();
       }
 
-      template< typename SuperDimensionsTag, typename MeshEntity>
+      template< typename SuperDimensionTag, typename MeshEntity>
       static typename MeshTraitsType::IdArrayAccessorType&
       superentityIdsArray( MeshEntity& entity )
       {
-         return entity.template superentityIdsArray< SuperDimensionsTag::value >();
+         return entity.template superentityIdsArray< SuperDimensionTag::value >();
       }
 
-      template<typename SubDimensionsTag, typename MeshEntity >
-      static typename MeshTraitsType::template SubentityTraits< typename MeshEntity::EntityTopology, SubDimensionsTag::value >::OrientationArrayType&
+      template<typename SubDimensionTag, typename MeshEntity >
+      static typename MeshTraitsType::template SubentityTraits< typename MeshEntity::EntityTopology, SubDimensionTag::value >::OrientationArrayType&
       subentityOrientationsArray( MeshEntity &entity )
       {
-         return entity.template subentityOrientationsArray< SubDimensionsTag::value >();
+         return entity.template subentityOrientationsArray< SubDimensionTag::value >();
       }
 
-      template< typename DimensionsTag >
-      typename MeshTraitsType::template EntityTraits< DimensionsTag::value >::StorageArrayType&
+      template< typename DimensionTag >
+      typename MeshTraitsType::template EntityTraits< DimensionTag::value >::StorageArrayType&
       meshEntitiesArray()
       {
-         return mesh->template entitiesArray< DimensionsTag >();
+         return mesh->template entitiesArray< DimensionTag >();
       }
 
-      template< typename DimensionsTag, typename SuperDimensionsTag >
+      template< typename DimensionTag, typename SuperDimensionTag >
       typename MeshTraitsType::GlobalIdArrayType&
       meshSuperentityIdsArray()
       {
-         return mesh->template superentityIdsArray< DimensionsTag, SuperDimensionsTag >();
+         return mesh->template superentityIdsArray< DimensionTag, SuperDimensionTag >();
       }
  
       template< typename EntityTopology, typename SuperdimensionsTag >
@@ -138,19 +144,19 @@ class MeshInitializer
          vertex.setPoint( point );
       }
 
-      template< typename DimensionsTag >
-      MeshSuperentityStorageInitializer< MeshConfig, typename MeshTraitsType::template EntityTraits< DimensionsTag::value >::EntityTopology >&
+      template< typename DimensionTag >
+      MeshSuperentityStorageInitializer< MeshConfig, typename MeshTraitsType::template EntityTraits< DimensionTag::value >::EntityTopology >&
       getSuperentityInitializer()
       {
-         return BaseType::getSuperentityInitializer( DimensionsTag() );
+         return BaseType::getSuperentityInitializer( DimensionTag() );
       }
 
  
-      template< typename DimensionsTag >
-      const MeshEntityReferenceOrientation< MeshConfig, typename MeshTraitsType::template EntityTraits< DimensionsTag::value >::EntityTopology >&
+      template< typename DimensionTag >
+      const MeshEntityReferenceOrientation< MeshConfig, typename MeshTraitsType::template EntityTraits< DimensionTag::value >::EntityTopology >&
       getReferenceOrientation( GlobalIndexType index) const
       {
-         return BaseType::getReferenceOrientation( DimensionsTag(), index);
+         return BaseType::getReferenceOrientation( DimensionTag(), index);
       }
 
    protected:
@@ -167,19 +173,19 @@ class MeshInitializer
  */
 template< typename MeshConfig >
 class MeshInitializerLayer< MeshConfig,
-                               typename MeshTraits< MeshConfig >::DimensionsTag,
+                               typename MeshTraits< MeshConfig >::DimensionTag,
                                true,
                                false >
    : public MeshInitializerLayer< MeshConfig,
-                                     typename MeshTraits< MeshConfig >::DimensionsTag::Decrement >
+                                     typename MeshTraits< MeshConfig >::DimensionTag::Decrement >
 {
    typedef MeshTraits< MeshConfig >                                              MeshTraitsType;
-   static const int Dimensions = MeshTraitsType::meshDimensions;
-   typedef MeshDimensionsTag< Dimensions >                                        DimensionsTag;
-   typedef MeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > BaseType;
+   static const int Dimension = MeshTraitsType::meshDimension;
+   typedef MeshDimensionTag< Dimension >                                        DimensionTag;
+   typedef MeshInitializerLayer< MeshConfig, typename DimensionTag::Decrement > BaseType;
 
    typedef Mesh< MeshConfig >                                                    MeshType;
-   typedef typename MeshTraitsType::template EntityTraits< Dimensions >          EntityTraitsType;
+   typedef typename MeshTraitsType::template EntityTraits< Dimension >          EntityTraitsType;
    typedef typename EntityTraitsType::EntityTopology                             EntityTopology;
    typedef typename MeshTraitsType::GlobalIndexType                              GlobalIndexType;
    typedef typename MeshTraitsType::CellTopology                                 CellTopology;
@@ -204,8 +210,8 @@ class MeshInitializerLayer< MeshConfig,
 
       void initEntities( InitializerType &initializer, const PointArrayType &points, const CellSeedArrayType &cellSeeds)
       {
-         StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >();
-         //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionTag >();
+         //cout << " Initiating entities with " << DimensionTag::value << " dimensions ... " << std::endl;
          entityArray.setSize( cellSeeds.getSize() );
          for( GlobalIndexType i = 0; i < entityArray.getSize(); i++ )
          {
@@ -226,7 +232,7 @@ class MeshInitializerLayer< MeshConfig,
       }
 
       using BaseType::getSuperentityInitializer;
-      SuperentityInitializerType& getSuperentityInitializer( DimensionsTag )
+      SuperentityInitializerType& getSuperentityInitializer( DimensionTag )
       {
          return this->superentityInitializer;
       }
@@ -260,7 +266,7 @@ class MeshInitializerLayer< MeshConfig,
       }
 
    private:
-      typedef  typename MeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType                     SeedIndexedSet;
+      typedef  typename MeshEntityTraits< MeshConfig, DimensionTag::value >::SeedIndexedSetType                     SeedIndexedSet;
 
       SeedIndexedSet seedsIndexedSet;
       SuperentityInitializerType superentityInitializer;
@@ -272,20 +278,20 @@ class MeshInitializerLayer< MeshConfig,
  * - entities orientation storage is turned off
  */
 template< typename MeshConfig,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshInitializerLayer< MeshConfig,
-                               DimensionsTag,
+                               DimensionTag,
                                true,
                                false >
    : public MeshInitializerLayer< MeshConfig,
-                                     typename DimensionsTag::Decrement >
+                                     typename DimensionTag::Decrement >
 {
       typedef MeshTraits< MeshConfig >                                           MeshTraitsType;
-   static const int Dimensions = DimensionsTag::value;
-   typedef MeshInitializerLayer< MeshConfig, typename DimensionsTag::Decrement > BaseType;
+   static const int Dimension = DimensionTag::value;
+   typedef MeshInitializerLayer< MeshConfig, typename DimensionTag::Decrement > BaseType;
 
    typedef Mesh< MeshConfig >                                                    MeshType;
-   typedef typename MeshTraitsType::template EntityTraits< Dimensions >          EntityTraitsType;
+   typedef typename MeshTraitsType::template EntityTraits< Dimension >          EntityTraitsType;
    typedef typename EntityTraitsType::EntityTopology                             EntityTopology;
    typedef typename MeshTraitsType::GlobalIndexType                              GlobalIndexType;
    typedef typename MeshTraitsType::CellTopology                                 CellTopology;
@@ -305,20 +311,20 @@ class MeshInitializerLayer< MeshConfig,
    typedef typename
       MeshSubentityTraits< MeshConfig,
                                 typename MeshConfig::CellTopology,
-                                DimensionsTag::value >::SubentityContainerType SubentitiesContainerType;
+                                DimensionTag::value >::SubentityContainerType SubentitiesContainerType;
  
    public:
 
       using BaseType::getEntityInitializer;
-      EntityInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index )
+      EntityInitializerType& getEntityInitializer( DimensionTag, GlobalIndexType index )
       {
          //return entityInitializerContainer[ index ];
       }
 
       void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds )
       {
-         typedef MeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionsTag >  SubentitySeedsCreator;
-         //cout << " Creating mesh entities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         typedef MeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionTag >  SubentitySeedsCreator;
+         //cout << " Creating mesh entities with " << DimensionTag::value << " dimensions ... " << std::endl;
          for( GlobalIndexType i = 0; i < cellSeeds.getSize(); i++ )
          {
             //cout << "  Creating mesh entities from cell number " << i << " : " << cellSeeds[ i ] << std::endl;
@@ -344,15 +350,15 @@ class MeshInitializerLayer< MeshConfig,
       }
  
       using BaseType::getSuperentityInitializer;
-      SuperentityInitializerType& getSuperentityInitializer( DimensionsTag )
+      SuperentityInitializerType& getSuperentityInitializer( DimensionTag )
       {
          return this->superentityInitializer;
       }
 
       void initEntities( InitializerType& initializer, const PointArrayType& points )
       {
-         StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >();
-         //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         StorageArrayType &entityArray = initializer.template meshEntitiesArray< DimensionTag >();
+         //cout << " Initiating entities with " << DimensionTag::value << " dimensions ... " << std::endl;
          entityArray.setSize( this->seedsIndexedSet.getSize() );
          EntitySeedArrayType seedsArray;
          seedsArray.setSize( this->seedsIndexedSet.getSize() );
@@ -372,7 +378,7 @@ class MeshInitializerLayer< MeshConfig,
       void createEntityReferenceOrientations() const {}
    private:
  
-      typedef  typename MeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType                     SeedIndexedSet;
+      typedef  typename MeshEntityTraits< MeshConfig, DimensionTag::value >::SeedIndexedSetType                     SeedIndexedSet;
       SeedIndexedSet seedsIndexedSet;
       SuperentityInitializerType superentityInitializer;
 };
@@ -383,20 +389,20 @@ class MeshInitializerLayer< MeshConfig,
  * - entities orientation storage is turned on
  */
 template< typename MeshConfig,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshInitializerLayer< MeshConfig,
-                            DimensionsTag,
+                            DimensionTag,
                             true,
                             true >
    : public MeshInitializerLayer< MeshConfig,
-                                     typename DimensionsTag::Decrement >
+                                     typename DimensionTag::Decrement >
 {
    typedef MeshInitializerLayer< MeshConfig,
-                                    typename DimensionsTag::Decrement >       BaseType;
+                                    typename DimensionTag::Decrement >       BaseType;
    typedef Mesh< MeshConfig >                                                 MeshType;
    typedef typename MeshType::MeshTraitsType                                  MeshTraitsType;
 
-   typedef typename MeshType::template EntityTraits< DimensionsTag::value >   EntityTraitsType;
+   typedef typename MeshType::template EntityTraits< DimensionTag::value >   EntityTraitsType;
    typedef typename EntityTraitsType::EntityTopology                          EntityTopology;
    typedef typename EntityTraitsType::EntityType                              EntityType;
    typedef typename EntityTraitsType::StorageArrayType                        ContainerType;
@@ -422,20 +428,20 @@ class MeshInitializerLayer< MeshConfig,
    typedef typename
       MeshSubentityTraits< MeshConfig,
                                 typename MeshConfig::CellTopology,
-                                DimensionsTag::value >::SubentityContainerType SubentitiesContainerType;
+                                DimensionTag::value >::SubentityContainerType SubentitiesContainerType;
 
    public:
  
       using BaseType::getEntityInitializer;
-      EntityInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index )
+      EntityInitializerType& getEntityInitializer( DimensionTag, GlobalIndexType index )
       {
          //return entityInitializerContainer[ index ];
       }
 
       void createEntitySeedsFromCellSeeds( const CellSeedArrayType& cellSeeds )
       {
-         typedef MeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionsTag >  SubentitySeedsCreator;
-         //cout << " Creating mesh entities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         typedef MeshSubentitySeedsCreator< MeshConfig, CellTopology, DimensionTag >  SubentitySeedsCreator;
+         //cout << " Creating mesh entities with " << DimensionTag::value << " dimensions ... " << std::endl;
          for( GlobalIndexType i = 0; i < cellSeeds.getSize(); i++ )
          {
             //cout << "  Creating mesh entities from cell number " << i << " : " << cellSeeds[ i ] << std::endl;
@@ -460,15 +466,15 @@ class MeshInitializerLayer< MeshConfig,
       }
  
       using BaseType::getSuperentityInitializer;
-      SuperentityInitializerType& getSuperentityInitializer( DimensionsTag )
+      SuperentityInitializerType& getSuperentityInitializer( DimensionTag )
       {
          return this->superentityInitializer;
       }
 
       void initEntities( InitializerType& initializer, const PointArrayType& points )
       {
-         EntityArrayType &entityArray = initializer.template meshEntitiesArray< DimensionsTag >();
-         //cout << " Initiating entities with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         EntityArrayType &entityArray = initializer.template meshEntitiesArray< DimensionTag >();
+         //cout << " Initiating entities with " << DimensionTag::value << " dimensions ... " << std::endl;
          entityArray.setSize( this->seedsIndexedSet.getSize() );
          SeedArrayType seedsArray;
          seedsArray.setSize( this->seedsIndexedSet.getSize() );
@@ -486,14 +492,14 @@ class MeshInitializerLayer< MeshConfig,
       }
 
       using BaseType::getReferenceOrientation;
-      const ReferenceOrientationType& getReferenceOrientation( DimensionsTag, GlobalIndexType index) const
+      const ReferenceOrientationType& getReferenceOrientation( DimensionTag, GlobalIndexType index) const
       {
          return this->referenceOrientations[ index ];
       }
  
       void createEntityReferenceOrientations()
       {
-         //cout << " Creating entity reference orientations with " << DimensionsTag::value << " dimensions ... " << std::endl;
+         //cout << " Creating entity reference orientations with " << DimensionTag::value << " dimensions ... " << std::endl;
          SeedArrayType seedsArray;
          seedsArray.setSize( this->seedsIndexedSet.getSize() );
          this->seedsIndexedSet.toArray( seedsArray );
@@ -508,7 +514,7 @@ class MeshInitializerLayer< MeshConfig,
  
    private:
  
-      typedef  typename MeshEntityTraits< MeshConfig, DimensionsTag::value >::SeedIndexedSetType                     SeedIndexedSet;
+      typedef  typename MeshEntityTraits< MeshConfig, DimensionTag::value >::SeedIndexedSetType                     SeedIndexedSet;
       SeedIndexedSet seedsIndexedSet;
       SuperentityInitializerType superentityInitializer;
       ReferenceOrientationArrayType referenceOrientations;
@@ -518,13 +524,13 @@ class MeshInitializerLayer< MeshConfig,
  * Mesh initializer layer for entities not being stored
  */
 template< typename MeshConfig,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshInitializerLayer< MeshConfig,
-                               DimensionsTag,
+                               DimensionTag,
                                false,
                                false >
    : public MeshInitializerLayer< MeshConfig,
-                                     typename DimensionsTag::Decrement >
+                                     typename DimensionTag::Decrement >
 {};
 
 /****
@@ -534,15 +540,15 @@ class MeshInitializerLayer< MeshConfig,
  */
 template< typename MeshConfig >
 class MeshInitializerLayer< MeshConfig,
-                               MeshDimensionsTag< 0 >,
+                               MeshDimensionTag< 0 >,
                                true,
                                false >
 {
    typedef Mesh< MeshConfig >                                                 MeshType;
    typedef typename MeshType::MeshTraitsType                                  MeshTraitsType;
-   typedef MeshDimensionsTag< 0 >                                              DimensionsTag;
+   typedef MeshDimensionTag< 0 >                                              DimensionTag;
 
-   typedef typename MeshType::template EntityTraits< DimensionsTag::value >   EntityTraitsType;
+   typedef typename MeshType::template EntityTraits< DimensionTag::value >   EntityTraitsType;
    typedef typename EntityTraitsType::EntityTopology                          EntityTopology;
    typedef typename EntityTraitsType::StorageArrayType                        ContainerType;
    typedef typename EntityTraitsType::AccessArrayType                         SharedContainerType;
@@ -570,13 +576,13 @@ class MeshInitializerLayer< MeshConfig,
 
       MeshType& getMesh()
       {
-         Assert( this->mesh, );
+         TNL_ASSERT( this->mesh, );
          return *( this->mesh );
       }
 
-      VertexInitializerType& getEntityInitializer( DimensionsTag, GlobalIndexType index )
+      VertexInitializerType& getEntityInitializer( DimensionTag, GlobalIndexType index )
       {
-         Assert( index >= 0 && index < vertexInitializerContainer.getSize(),
+         TNL_ASSERT( index >= 0 && index < vertexInitializerContainer.getSize(),
                   std::cerr << " index = " << index
                        << " vertexInitializerContainer.getSize() = " << vertexInitializerContainer.getSize() << std::endl; );
          return vertexInitializerContainer[ index ];
@@ -586,7 +592,7 @@ class MeshInitializerLayer< MeshConfig,
  
       void initEntities( InitializerType& initializer, const PointArrayType& points )
       {
-         EntityArrayType &vertexArray = initializer.template meshEntitiesArray< DimensionsTag >();
+         EntityArrayType &vertexArray = initializer.template meshEntitiesArray< DimensionTag >();
          vertexArray.setSize( points.getSize() );
          for( GlobalIndexType i = 0; i < vertexArray.getSize(); i++ )
             EntityInitializerType::setVertexPoint( vertexArray[i], points[i], initializer );
@@ -598,10 +604,10 @@ class MeshInitializerLayer< MeshConfig,
 
       void createEntityInitializers()
       {
-         vertexInitializerContainer.setSize( this->getMesh().template getNumberOfEntities< DimensionsTag::value >() );
+         vertexInitializerContainer.setSize( this->getMesh().template getNumberOfEntities< DimensionTag::value >() );
       }
  
-      SuperentityInitializerType& getSuperentityInitializer( DimensionsTag )
+      SuperentityInitializerType& getSuperentityInitializer( DimensionTag )
       {
          return this->superentityInitializer;
       }
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshSubentitySeedCreator.h b/src/TNL/Meshes/MeshDetails/initializer/MeshSubentitySeedCreator.h
index 3e5233e8344b205442b78c27328a4dba1a0044ed..f7069f4cf5d5e674f61b37d8f604a10dd0c17140 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshSubentitySeedCreator.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshSubentitySeedCreator.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/StaticFor.h>
@@ -17,11 +23,11 @@ namespace Meshes {
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename SubDimensionsTag >
+          typename SubDimensionTag >
 class MeshSubentitySeedsCreator
 {
 	typedef typename MeshTraits< MeshConfig >::LocalIndexType                                                      LocalIndexType;
-	typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, SubDimensionsTag::value > SubentityTraits;
+	typedef typename MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, SubDimensionTag::value > SubentityTraits;
 	typedef typename SubentityTraits::SubentityTopology                                                               SubentityTopology;
 	typedef typename MeshTraits< MeshConfig >::IdArrayAccessorType                                                 IdArrayAccessorType;
 	typedef typename MeshTraits< MeshConfig >::template SubentityTraits< SubentityTopology, 0 >                    SubentityVertexTraits;
@@ -32,7 +38,7 @@ class MeshSubentitySeedsCreator
    public:
       typedef typename SubentityTraits::SeedArrayType SubentitySeedArray;
       typedef MeshEntitySeed< MeshConfig, EntityTopology >  EntitySeed;
-      //typedef typename MeshEntityTraits< MeshConfig, SubDimensionsTag >::SeedIndexedSetType                     SeedIndexedSet;
+      //typedef typename MeshEntityTraits< MeshConfig, SubDimensionTag >::SeedIndexedSetType                     SeedIndexedSet;
 
       //template< typename SeedIndexedSet >
       static SubentitySeedArray create( const EntitySeed &entitySeed  )
diff --git a/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
index af39848bfaa7c7dde09e2df5fe29d81bf4b43781..587cb03a30c89f22a82a05045ef2dad456b3ab02 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/MeshSuperentityStorageInitializer.h
@@ -8,9 +8,15 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 #include <algorithm>
 #include <vector>
 
@@ -22,48 +28,48 @@ class MeshInitializer;
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag,
-          bool SuperentityStorage = MeshSuperentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >::storageEnabled >
+          typename DimensionTag,
+          bool SuperentityStorage = MeshSuperentityTraits< MeshConfig, EntityTopology, DimensionTag::value >::storageEnabled >
 class MeshSuperentityStorageInitializerLayer;
 
 template< typename MeshConfig,
           typename EntityTopology >
 class MeshSuperentityStorageInitializer :
-   public MeshSuperentityStorageInitializerLayer< MeshConfig, EntityTopology, MeshDimensionsTag< MeshTraits< MeshConfig >::meshDimensions > >
+   public MeshSuperentityStorageInitializerLayer< MeshConfig, EntityTopology, MeshDimensionTag< MeshTraits< MeshConfig >::meshDimension > >
 {};
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          DimensionsTag,
+                                          DimensionTag,
                                           true >
    : public MeshSuperentityStorageInitializerLayer< MeshConfig,
                                                 EntityTopology,
-                                                typename DimensionsTag::Decrement >
+                                                typename DimensionTag::Decrement >
 {
    typedef MeshSuperentityStorageInitializerLayer< MeshConfig,
                                                       EntityTopology,
-                                                      typename DimensionsTag::Decrement >      BaseType;
+                                                      typename DimensionTag::Decrement >      BaseType;
 
-   static const int Dimensions = DimensionsTag::value;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >                                       EntityDimensions;
+   static const int Dimension = DimensionTag::value;
+   typedef MeshDimensionTag< EntityTopology::dimensions >                                       EntityDimension;
 	
    typedef MeshTraits< MeshConfig >                                                             MeshTraitsType;
    typedef typename MeshTraitsType::GlobalIdArrayType                                           GlobalIdArrayType; 
    typedef typename MeshTraitsType::GlobalIndexType                                             GlobalIndexType;
    typedef typename MeshTraitsType::LocalIndexType                                              LocalIndexType;
    typedef MeshInitializer< MeshConfig >                                                        MeshInitializerType;
-   typedef typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimensions >    SuperentityTraitsType;
+   typedef typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimension >    SuperentityTraitsType;
    typedef typename SuperentityTraitsType::StorageNetworkType                                   SuperentityStorageNetwork;
 
    public:
       using BaseType::addSuperentity;
 	
-      void addSuperentity( DimensionsTag, GlobalIndexType entityIndex, GlobalIndexType superentityIndex)
+      void addSuperentity( DimensionTag, GlobalIndexType entityIndex, GlobalIndexType superentityIndex)
       {
-         //cout << "Adding superentity with " << DimensionsTag::value << " dimensions of enity with " << EntityDimensions::value << " ... " << std::endl;
+         //cout << "Adding superentity with " << DimensionTag::value << " dimensions of enity with " << EntityDimension::value << " ... " << std::endl;
          indexPairs.push_back( IndexPair{ entityIndex, superentityIndex } );
       }
 
@@ -75,11 +81,11 @@ class MeshSuperentityStorageInitializerLayer< MeshConfig,
                     indexPairs.end(),
                     []( IndexPair pair0, IndexPair pair1 ){ return ( pair0.entityIndex < pair1.entityIndex ); } );*/
 
-         GlobalIdArrayType &superentityIdsArray = meshInitializer.template meshSuperentityIdsArray< EntityDimensions, DimensionsTag >();
+         GlobalIdArrayType &superentityIdsArray = meshInitializer.template meshSuperentityIdsArray< EntityDimension, DimensionTag >();
          superentityIdsArray.setSize( static_cast< GlobalIndexType >( indexPairs.size() )  );
          GlobalIndexType currentBegin = 0;
          GlobalIndexType lastEntityIndex = 0;
-        std::cout << "There are " << superentityIdsArray.getSize() << " superentities with " << DimensionsTag::value << " dimensions of enities with " << EntityDimensions::value << " ... " << std::endl;
+        std::cout << "There are " << superentityIdsArray.getSize() << " superentities with " << DimensionTag::value << " dimensions of enities with " << EntityDimension::value << " ... " << std::endl;
          for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
          {
             superentityIdsArray[ i ] = indexPairs[i].superentityIndex;
@@ -87,26 +93,26 @@ class MeshSuperentityStorageInitializerLayer< MeshConfig,
             //cout << "Adding superentity " << indexPairs[i].superentityIndex << " to entity " << lastEntityIndex << std::endl;
             if( indexPairs[ i ].entityIndex != lastEntityIndex )
             {
-               meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, i - currentBegin );
+               meshInitializer.template superentityIdsArray< DimensionTag >( meshInitializer.template meshEntitiesArray< EntityDimension >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, i - currentBegin );
                currentBegin = i;
                lastEntityIndex = indexPairs[ i ].entityIndex;
             }
          }
 
-         meshInitializer.template superentityIdsArray< DimensionsTag >( meshInitializer.template meshEntitiesArray< EntityDimensions >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, superentityIdsArray.getSize() - currentBegin );
+         meshInitializer.template superentityIdsArray< DimensionTag >( meshInitializer.template meshEntitiesArray< EntityDimension >()[ lastEntityIndex ] ).bind( superentityIdsArray, currentBegin, superentityIdsArray.getSize() - currentBegin );
          indexPairs.clear();
  
          /****
           * Network initializer
           */
-         SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, DimensionsTag >();
+         SuperentityStorageNetwork& superentityStorageNetwork = meshInitializer.template meshSuperentityStorageNetwork< EntityTopology, DimensionTag >();
          //GlobalIndexType lastEntityIndex( 0 );
          superentityStorageNetwork.setRanges(
-            meshInitializer.template meshEntitiesArray< EntityDimensions >().getSize(),
-            meshInitializer.template meshEntitiesArray< DimensionsTag >().getSize() );
+            meshInitializer.template meshEntitiesArray< EntityDimension >().getSize(),
+            meshInitializer.template meshEntitiesArray< DimensionTag >().getSize() );
          lastEntityIndex = 0;
          typename SuperentityStorageNetwork::ValuesAllocationVectorType storageNetworkAllocationVector;
-         storageNetworkAllocationVector.setSize( meshInitializer.template meshEntitiesArray< EntityDimensions >().getSize() );
+         storageNetworkAllocationVector.setSize( meshInitializer.template meshEntitiesArray< EntityDimension >().getSize() );
          storageNetworkAllocationVector.setValue( 0 );
          for( GlobalIndexType i = 0; i < superentityIdsArray.getSize(); i++)
          {
@@ -145,18 +151,18 @@ class MeshSuperentityStorageInitializerLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          DimensionsTag,
+                                          DimensionTag,
                                           false >
    : public MeshSuperentityStorageInitializerLayer< MeshConfig,
                                                 EntityTopology,
-                                                typename DimensionsTag::Decrement >
+                                                typename DimensionTag::Decrement >
 {
    typedef MeshSuperentityStorageInitializerLayer< MeshConfig,
                                                 EntityTopology,
-                                                typename DimensionsTag::Decrement > BaseType;
+                                                typename DimensionTag::Decrement > BaseType;
    typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
  
    public:
@@ -169,7 +175,7 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          MeshDimensionsTag< EntityTopology::dimensions >,
+                                          MeshDimensionTag< EntityTopology::dimensions >,
                                           true >
 {
    typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
@@ -183,7 +189,7 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshSuperentityStorageInitializerLayer< MeshConfig,
                                           EntityTopology,
-                                          MeshDimensionsTag< EntityTopology::dimensions >,
+                                          MeshDimensionTag< EntityTopology::dimensions >,
                                           false >
 {
    typedef MeshInitializer< MeshConfig >                                      MeshInitializerType;
diff --git a/src/TNL/Meshes/MeshDetails/layers/CMakeLists.txt b/src/TNL/Meshes/MeshDetails/layers/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
index 00b7ed5e912346242a633dc7637d15499c23836f..bd31795a5cb2d774d8a76e87aa6c4c99b96dcab4 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshStorageLayer.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/File.h>
@@ -19,35 +25,35 @@ namespace TNL {
 namespace Meshes {
 
 template< typename MeshConfig,
-          typename DimensionsTag,
-          bool EntityStorage = MeshEntityTraits< MeshConfig, DimensionsTag::value >::storageEnabled >
+          typename DimensionTag,
+          bool EntityStorage = MeshEntityTraits< MeshConfig, DimensionTag::value >::storageEnabled >
 class MeshStorageLayer;
 
 
 template< typename MeshConfig >
 class MeshStorageLayers
-   : public MeshStorageLayer< MeshConfig, typename MeshTraits< MeshConfig >::DimensionsTag >
+   : public MeshStorageLayer< MeshConfig, typename MeshTraits< MeshConfig >::DimensionTag >
 {
 };
 
 
 template< typename MeshConfig,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshStorageLayer< MeshConfig,
-                           DimensionsTag,
+                           DimensionTag,
                            true >
-   : public MeshStorageLayer< MeshConfig, typename DimensionsTag::Decrement >,
+   : public MeshStorageLayer< MeshConfig, typename DimensionTag::Decrement >,
      public MeshSuperentityStorageLayers< MeshConfig,
-                                             typename MeshTraits< MeshConfig >::template EntityTraits< DimensionsTag::value >::EntityTopology >
+                                             typename MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::EntityTopology >
 {
    public:
 
-      static const int Dimensions = DimensionsTag::value;
-      typedef MeshStorageLayer< MeshConfig, typename DimensionsTag::Decrement >   BaseType;
+      static const int Dimension = DimensionTag::value;
+      typedef MeshStorageLayer< MeshConfig, typename DimensionTag::Decrement >   BaseType;
       typedef MeshSuperentityStorageLayers< MeshConfig,
-                                               typename MeshTraits< MeshConfig >::template EntityTraits< DimensionsTag::value >::EntityTopology > SuperentityStorageBaseType;
+                                               typename MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::EntityTopology > SuperentityStorageBaseType;
       typedef MeshTraits< MeshConfig >                                             MeshTraitsType;
-      typedef typename MeshTraitsType::template EntityTraits< Dimensions >         EntityTraitsType;
+      typedef typename MeshTraitsType::template EntityTraits< Dimension >         EntityTraitsType;
 
       typedef typename EntityTraitsType::StorageArrayType                          StorageArrayType;
       typedef typename EntityTraitsType::AccessArrayType                           AccessArrayType;
@@ -64,29 +70,29 @@ class MeshStorageLayer< MeshConfig,
       {
       }
 
-      GlobalIndexType getNumberOfEntities( DimensionsTag ) const
+      GlobalIndexType getNumberOfEntities( DimensionTag ) const
       {
          return this->entities.getSize();
       }
 
-      EntityType& getEntity( DimensionsTag,
+      EntityType& getEntity( DimensionTag,
                              const GlobalIndexType entityIndex )
       {
          return this->entities[ entityIndex ];
       }
 
-      const EntityType& getEntity( DimensionsTag,
+      const EntityType& getEntity( DimensionTag,
                                    const GlobalIndexType entityIndex ) const
       {
          return this->entities[ entityIndex ];
       }
 
-      AccessArrayType& getEntities( DimensionsTag )
+      AccessArrayType& getEntities( DimensionTag )
       {
          return this->sharedEntities;
       }
 
-      const AccessArrayType& getEntities( DimensionsTag ) const
+      const AccessArrayType& getEntities( DimensionTag ) const
       {
          return this->sharedEntities;
       }
@@ -96,7 +102,7 @@ class MeshStorageLayer< MeshConfig,
          if( ! BaseType::save( file ) ||
              ! this->entities.save( file ) )
          {
-            std::cerr << "Saving of the mesh entities with " << DimensionsTag::value << " dimensions failed." << std::endl;
+            std::cerr << "Saving of the mesh entities with " << DimensionTag::value << " dimensions failed." << std::endl;
             return false;
          }
          return true;
@@ -104,11 +110,11 @@ class MeshStorageLayer< MeshConfig,
 
       bool load( File& file )
       {
-         //cout << "Loading mesh layer with dimensions " << DimensionsTag::value << std::endl;
+         //cout << "Loading mesh layer with dimensions " << DimensionTag::value << std::endl;
          if( ! BaseType::load( file ) ||
              ! this->entities.load( file ) )
          {
-            std::cerr << "Loading of the mesh entities with " << DimensionsTag::value << " dimensions failed." << std::endl;
+            std::cerr << "Loading of the mesh entities with " << DimensionTag::value << " dimensions failed." << std::endl;
             return false;
          }
          this->entitiesAccess.bind( this->entities );
@@ -118,7 +124,7 @@ class MeshStorageLayer< MeshConfig,
       void print( std::ostream& str ) const
       {
          BaseType::print( str );
-         str << "The entities with " << DimensionsTag::value << " dimensions are: " << std::endl;
+         str << "The entities with " << DimensionTag::value << " dimensions are: " << std::endl;
          for( GlobalIndexType i = 0; i < entities.getSize();i ++ )
          {
             str << i << " ";
@@ -144,44 +150,44 @@ class MeshStorageLayer< MeshConfig,
 
       using BaseType::entitiesArray;
  
-      typename EntityTraitsType::StorageArrayType& entitiesArray( DimensionsTag )
+      typename EntityTraitsType::StorageArrayType& entitiesArray( DimensionTag )
       {
          return entities;
       }
  
       using BaseType::superentityIdsArray;
 	
-      template< typename SuperDimensionsTag >
-      typename MeshTraitsType::GlobalIdArrayType& superentityIdsArray( DimensionsTag )
+      template< typename SuperDimensionTag >
+      typename MeshTraitsType::GlobalIdArrayType& superentityIdsArray( DimensionTag )
       {
-         return SuperentityStorageBaseType::superentityIdsArray( SuperDimensionsTag() );
+         return SuperentityStorageBaseType::superentityIdsArray( SuperDimensionTag() );
       }
  
       using BaseType::getSuperentityStorageNetwork;
       template< typename SuperdimensionsTag >
       typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionsTag::value >::StorageNetworkType&
-      getSuperentityStorageNetwork( MeshDimensionsTag< EntityTopology::dimensions > )
+      getSuperentityStorageNetwork( MeshDimensionTag< EntityTopology::dimensions > )
       {
          return SuperentityStorageBaseType::getStorageNetwork( SuperdimensionsTag() );
       }
 };
 
 template< typename MeshConfig,
-          typename DimensionsTag >
-class MeshStorageLayer< MeshConfig, DimensionsTag, false >
-   : public MeshStorageLayer< MeshConfig, typename DimensionsTag::Decrement  >
+          typename DimensionTag >
+class MeshStorageLayer< MeshConfig, DimensionTag, false >
+   : public MeshStorageLayer< MeshConfig, typename DimensionTag::Decrement  >
 {
 };
 
 template< typename MeshConfig >
-class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
+class MeshStorageLayer< MeshConfig, MeshDimensionTag< 0 >, true > :
    public MeshSuperentityStorageLayers< MeshConfig,
                                            MeshVertexTopology >
 
 {
    public:
 
-   typedef MeshDimensionsTag< 0 >                        DimensionsTag;
+   typedef MeshDimensionTag< 0 >                        DimensionTag;
  
    typedef MeshSuperentityStorageLayers< MeshConfig,
                                             MeshVertexTopology >     SuperentityStorageBaseType;
@@ -233,29 +239,29 @@ class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
     * with higher dimensions entities storage layers.
     */
 
-   GlobalIndexType getNumberOfEntities( DimensionsTag ) const
+   GlobalIndexType getNumberOfEntities( DimensionTag ) const
    {
       return this->vertices.getSize();
    }
 
-   VertexType& getEntity( DimensionsTag,
+   VertexType& getEntity( DimensionTag,
                           const GlobalIndexType entityIndex )
    {
       return this->vertices[ entityIndex ];
    }
 
-   const VertexType& getEntity( DimensionsTag,
+   const VertexType& getEntity( DimensionTag,
                                 const GlobalIndexType entityIndex ) const
    {
       return this->vertices.getElement( entityIndex );
    }
 
-   AccessArrayType& getEntities( DimensionsTag )
+   AccessArrayType& getEntities( DimensionTag )
    {
       return this->sharedVertices;
    }
 
-   const AccessArrayType& getEntities( DimensionsTag ) const
+   const AccessArrayType& getEntities( DimensionTag ) const
    {
       return this->sharedVertices;
    }
@@ -264,7 +270,7 @@ class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
    {
       if( ! this->vertices.save( file ) )
       {
-         std::cerr << "Saving of the mesh entities with " << DimensionsTag::value << " dimensions failed." << std::endl;
+         std::cerr << "Saving of the mesh entities with " << DimensionTag::value << " dimensions failed." << std::endl;
          return false;
       }
       return true;
@@ -274,7 +280,7 @@ class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
    {
       if( ! this->vertices.load( file ) )
       {
-         std::cerr << "Loading of the mesh entities with " << DimensionsTag::value << " dimensions failed." << std::endl;
+         std::cerr << "Loading of the mesh entities with " << DimensionTag::value << " dimensions failed." << std::endl;
          return false;
       }
       this->verticesAccess.bind( this->vertices );
@@ -305,20 +311,20 @@ class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
    // TODO: this is only for the mesh initializer - fix it
    public:
  
-      typename EntityTraitsType::StorageArrayType& entitiesArray( DimensionsTag )
+      typename EntityTraitsType::StorageArrayType& entitiesArray( DimensionTag )
       {
          return vertices;
       }
 
  
-      template< typename SuperDimensionsTag >
-      typename MeshTraitsType::GlobalIdArrayType& superentityIdsArray( DimensionsTag )
+      template< typename SuperDimensionTag >
+      typename MeshTraitsType::GlobalIdArrayType& superentityIdsArray( DimensionTag )
       {
-         return SuperentityStorageBaseType::superentityIdsArray( SuperDimensionsTag() );
+         return SuperentityStorageBaseType::superentityIdsArray( SuperDimensionTag() );
       }
 
       template< typename SuperdimensionsTag >
-      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionsTag::value >::StorageNetworkType& getSuperentityStorageNetwork( MeshDimensionsTag< EntityTopology::dimensions > )
+      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperdimensionsTag::value >::StorageNetworkType& getSuperentityStorageNetwork( MeshDimensionTag< EntityTopology::dimensions > )
       {
          return SuperentityStorageBaseType::getStorageNetwork( SuperdimensionsTag() );
       }
@@ -329,7 +335,7 @@ class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, true > :
  * Forces termination of recursive inheritance (prevents compiler from generating huge error logs)
  */
 template< typename MeshConfig >
-class MeshStorageLayer< MeshConfig, MeshDimensionsTag< 0 >, false >
+class MeshStorageLayer< MeshConfig, MeshDimensionTag< 0 >, false >
 {
 };
 
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
index 955aa90d3da214b7624d714f93e410b5d54d97ac..13d40fd980f9616741eaf14986c6010ab9fb9beb 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h
@@ -8,10 +8,16 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/File.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h>
 #include <TNL/Meshes/MeshDetails/MeshEntityOrientation.h>
 
@@ -20,11 +26,11 @@ namespace Meshes {
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag,
+          typename DimensionTag,
           bool SubentityStorage =
-            MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag::value >::storageEnabled,
+            MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag::value >::storageEnabled,
           bool SubentityOrientationStorage =
-            MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionsTag::value >::orientationEnabled >
+            MeshTraits< MeshConfig >::template SubentityTraits< EntityTopology, DimensionTag::value >::orientationEnabled >
 class MeshSubentityStorageLayer;
 
 
@@ -33,32 +39,32 @@ template< typename MeshConfig,
 class MeshSubentityStorageLayers
    : public MeshSubentityStorageLayer< MeshConfig,
                                           EntityTopology,
-                                          MeshDimensionsTag< EntityTopology::dimensions - 1 > >
+                                          MeshDimensionTag< EntityTopology::dimensions - 1 > >
 {
 };
 
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshSubentityStorageLayer< MeshConfig,
                                     EntityTopology,
-                                    DimensionsTag,
+                                    DimensionTag,
                                     true,
                                     true >
    : public MeshSubentityStorageLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >
+                                          typename DimensionTag::Decrement >
 {
    typedef MeshSubentityStorageLayer< MeshConfig,
                                          EntityTopology,
-                                         typename DimensionsTag::Decrement > BaseType;
+                                         typename DimensionTag::Decrement > BaseType;
 
    protected:
 
-   static const int Dimensions = DimensionsTag::value;
+   static const int Dimension = DimensionTag::value;
    typedef MeshTraits< MeshConfig >                                                      MeshTraitsType;
-   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimensions >   SubentityTraitsType;
+   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimension >   SubentityTraitsType;
    typedef typename MeshTraitsType::GlobalIndexType                                          GlobalIndexType;
    typedef typename MeshTraitsType::LocalIndexType                                           LocalIndexType;
    typedef typename SubentityTraitsType::IdArrayType                                         IdArrayType;
@@ -72,7 +78,7 @@ class MeshSubentityStorageLayer< MeshConfig,
 
    ~MeshSubentityStorageLayer()
    {
-      //cout << "      Destroying " << this->sharedSubentitiesIndices.getSize() << " subentities with "<< DimensionsTag::value << " dimensions." << std::endl;
+      //cout << "      Destroying " << this->sharedSubentitiesIndices.getSize() << " subentities with "<< DimensionTag::value << " dimensions." << std::endl;
    }
 
    MeshSubentityStorageLayer& operator = ( const MeshSubentityStorageLayer& layer )
@@ -87,7 +93,7 @@ class MeshSubentityStorageLayer< MeshConfig,
       if( ! BaseType::save( file ) ||
           ! this->subentitiesIndices.save( file ) )
       {
-         std::cerr << "Saving of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Saving of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -98,7 +104,7 @@ class MeshSubentityStorageLayer< MeshConfig,
       if( ! BaseType::load( file ) ||
           ! this->subentitiesIndices.load( file ) )
       {
-         std::cerr << "Loading of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Loading of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -108,7 +114,7 @@ class MeshSubentityStorageLayer< MeshConfig,
    {
       BaseType::print( str );
       str << std::endl;
-      str << "\t Subentities with " << DimensionsTag::value << " dimensions are: " << subentitiesIndices << ".";
+      str << "\t Subentities with " << DimensionTag::value << " dimensions are: " << subentitiesIndices << ".";
    }
 
    bool operator==( const MeshSubentityStorageLayer& layer  ) const
@@ -126,32 +132,32 @@ class MeshSubentityStorageLayer< MeshConfig,
    /****
     * Define setter/getter for the current level of the subentities
     */
-   void setSubentityIndex( DimensionsTag,
+   void setSubentityIndex( DimensionTag,
                            const LocalIndexType localIndex,
                            const GlobalIndexType globalIndex )
    {
       this->subentitiesIndices[ localIndex ] = globalIndex;
    }
 
-   GlobalIndexType getSubentityIndex( DimensionsTag,
+   GlobalIndexType getSubentityIndex( DimensionTag,
                                       const LocalIndexType localIndex ) const
    {
       return this->subentitiesIndices[ localIndex ];
    }
 
    using BaseType::subentityIdsArray;
-   IdArrayType& subentityIdsArray( DimensionsTag ) { return this->subentitiesIndices; }
+   IdArrayType& subentityIdsArray( DimensionTag ) { return this->subentitiesIndices; }
  
    using BaseType::subentityOrientation;
-   IdPermutationArrayAccessorType subentityOrientation( DimensionsTag, LocalIndexType index) const
+   IdPermutationArrayAccessorType subentityOrientation( DimensionTag, LocalIndexType index) const
    {
-      Assert( 0 <= index && index < SubentityTraitsType::count, );
+      TNL_ASSERT( 0 <= index && index < SubentityTraitsType::count, );
  
       return this->subentityOrientations[ index ].getSubvertexPermutation();
    }
 
    using BaseType::subentityOrientationsArray;
-	OrientationArrayType& subentityOrientationsArray( DimensionsTag ) { return this->subentityOrientations; }
+	OrientationArrayType& subentityOrientationsArray( DimensionTag ) { return this->subentityOrientations; }
  
    private:
       IdArrayType subentitiesIndices;
@@ -162,25 +168,25 @@ class MeshSubentityStorageLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshSubentityStorageLayer< MeshConfig,
                                     EntityTopology,
-                                    DimensionsTag,
+                                    DimensionTag,
                                     true,
                                     false >
    : public MeshSubentityStorageLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >
+                                          typename DimensionTag::Decrement >
 {
    typedef MeshSubentityStorageLayer< MeshConfig,
                                          EntityTopology,
-                                         typename DimensionsTag::Decrement > BaseType;
+                                         typename DimensionTag::Decrement > BaseType;
 
    protected:
  
-   static const int Dimensions = DimensionsTag::value;
+   static const int Dimension = DimensionTag::value;
    typedef MeshTraits< MeshConfig >                                                      MeshTraitsType;
-   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimensions >   SubentityTraitsType;
+   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimension >   SubentityTraitsType;
    typedef typename MeshTraitsType::GlobalIndexType                                          GlobalIndexType;
    typedef typename MeshTraitsType::LocalIndexType                                           LocalIndexType;
    typedef typename SubentityTraitsType::IdArrayType                                         IdArrayType;
@@ -194,7 +200,7 @@ class MeshSubentityStorageLayer< MeshConfig,
 
    ~MeshSubentityStorageLayer()
    {
-      //cout << "      Destroying " << this->sharedSubentitiesIndices.getSize() << " subentities with "<< DimensionsTag::value << " dimensions." << std::endl;
+      //cout << "      Destroying " << this->sharedSubentitiesIndices.getSize() << " subentities with "<< DimensionTag::value << " dimensions." << std::endl;
    }
 
    MeshSubentityStorageLayer& operator = ( const MeshSubentityStorageLayer& layer )
@@ -209,7 +215,7 @@ class MeshSubentityStorageLayer< MeshConfig,
       if( ! BaseType::save( file ) ||
           ! this->subentitiesIndices.save( file ) )
       {
-         std::cerr << "Saving of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Saving of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -220,7 +226,7 @@ class MeshSubentityStorageLayer< MeshConfig,
       if( ! BaseType::load( file ) ||
           ! this->subentitiesIndices.load( file ) )
       {
-         std::cerr << "Loading of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Loading of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -230,7 +236,7 @@ class MeshSubentityStorageLayer< MeshConfig,
    {
       BaseType::print( str );
       str << std::endl;
-      str << "\t Subentities with " << DimensionsTag::value << " dimensions are: " << subentitiesIndices << ".";
+      str << "\t Subentities with " << DimensionTag::value << " dimensions are: " << subentitiesIndices << ".";
    }
 
    bool operator==( const MeshSubentityStorageLayer& layer  ) const
@@ -248,21 +254,21 @@ class MeshSubentityStorageLayer< MeshConfig,
    /****
     * Define setter/getter for the current level of the subentities
     */
-   void setSubentityIndex( DimensionsTag,
+   void setSubentityIndex( DimensionTag,
                            const LocalIndexType localIndex,
                            const GlobalIndexType globalIndex )
    {
       this->subentitiesIndices[ localIndex ] = globalIndex;
    }
 
-   GlobalIndexType getSubentityIndex( DimensionsTag,
+   GlobalIndexType getSubentityIndex( DimensionTag,
                                       const LocalIndexType localIndex ) const
    {
       return this->subentitiesIndices[ localIndex ];
    }
 
    using BaseType::subentityIdsArray;
-   IdArrayType& subentityIdsArray( DimensionsTag ) { return this->subentitiesIndices; }
+   IdArrayType& subentityIdsArray( DimensionTag ) { return this->subentitiesIndices; }
  
    using BaseType::subentityOrientationsArray;
    void subentityOrientationsArray() {}
@@ -273,15 +279,15 @@ class MeshSubentityStorageLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
+          typename DimensionTag >
 class MeshSubentityStorageLayer< MeshConfig,
                                     EntityTopology,
-                                    DimensionsTag,
+                                    DimensionTag,
                                     false,
                                     false >
    : public MeshSubentityStorageLayer< MeshConfig,
                                           EntityTopology,
-                                          typename DimensionsTag::Decrement >
+                                          typename DimensionTag::Decrement >
 {
 };
 
@@ -290,16 +296,16 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshSubentityStorageLayer< MeshConfig,
                                     EntityTopology,
-                                    MeshDimensionsTag< 0 >,
+                                    MeshDimensionTag< 0 >,
                                     true,
                                     false >
 {
-   typedef MeshDimensionsTag< 0 >                           DimensionsTag;
+   typedef MeshDimensionTag< 0 >                           DimensionTag;
 
    protected:
-   static const int Dimensions = 0;
+   static const int Dimension = 0;
    typedef MeshTraits< MeshConfig >                                                          MeshTraitsType;
-   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimensions >   SubentityTraitsType;
+   typedef typename MeshTraitsType::template SubentityTraits< EntityTopology, Dimension >   SubentityTraitsType;
    typedef typename MeshTraitsType::GlobalIndexType                                          GlobalIndexType;
    typedef typename MeshTraitsType::LocalIndexType                                           LocalIndexType;
    typedef typename SubentityTraitsType::IdArrayType                                         IdArrayType;
@@ -311,7 +317,7 @@ class MeshSubentityStorageLayer< MeshConfig,
 
    ~MeshSubentityStorageLayer()
    {
-      //cout << "      Destroying " << this->sharedVerticesIndices.getSize() << " subentities with "<< DimensionsTag::value << " dimensions." << std::endl;
+      //cout << "      Destroying " << this->sharedVerticesIndices.getSize() << " subentities with "<< DimensionTag::value << " dimensions." << std::endl;
    }
 
 
@@ -325,7 +331,7 @@ class MeshSubentityStorageLayer< MeshConfig,
    {
       if( ! this->verticesIndices.save( file ) )
       {
-         std::cerr << "Saving of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Saving of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -335,7 +341,7 @@ class MeshSubentityStorageLayer< MeshConfig,
    {
       if( ! this->verticesIndices.load( file ) )
       {
-         std::cerr << "Loading of the entity subentities layer with " << DimensionsTag::value << " failed." << std::endl;
+         std::cerr << "Loading of the entity subentities layer with " << DimensionTag::value << " failed." << std::endl;
          return false;
       }
       return true;
@@ -343,7 +349,7 @@ class MeshSubentityStorageLayer< MeshConfig,
 
    void print( std::ostream& str ) const
    {
-      str << "\t Subentities with " << DimensionsTag::value << " dimensions are: " << this->verticesIndices << ".";
+      str << "\t Subentities with " << DimensionTag::value << " dimensions are: " << this->verticesIndices << ".";
    }
 
    bool operator==( const MeshSubentityStorageLayer& layer  ) const
@@ -351,19 +357,19 @@ class MeshSubentityStorageLayer< MeshConfig,
       return ( verticesIndices == layer.verticesIndices );
    }
 
-   GlobalIndexType getSubentityIndex( DimensionsTag,
+   GlobalIndexType getSubentityIndex( DimensionTag,
                                       const LocalIndexType localIndex ) const
    {
       return this->verticesIndices[ localIndex ];
    }
-   void setSubentityIndex( DimensionsTag,
+   void setSubentityIndex( DimensionTag,
                            const LocalIndexType localIndex,
                            const GlobalIndexType globalIndex )
    {
       this->verticesIndices[ localIndex ] = globalIndex;
    }
 
-   IdArrayType& subentityIdsArray( DimensionsTag ) { return this->verticesIndices; }
+   IdArrayType& subentityIdsArray( DimensionTag ) { return this->verticesIndices; }
  
    protected:
  
@@ -380,7 +386,7 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshSubentityStorageLayer< MeshConfig,
                                     EntityTopology,
-                                    MeshDimensionsTag< 0 >,
+                                    MeshDimensionTag< 0 >,
                                     false,
                                     false >
 {
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
index 79c11d294c288a403862b5f1641ac7e2cca5ff16..44476c81cdb57ce40482ba63b5b62206176dfc8f 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccess.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
@@ -17,9 +23,9 @@ namespace Meshes {
 
 template< typename MeshConfig,
           typename MeshEntity,
-          typename DimensionsTag,
+          typename DimensionTag,
           bool SuperentityStorage =
-             MeshTraits< MeshConfig >::template SuperentityTraits< MeshEntity, DimensionsTag::value >::storageEnabled >
+             MeshTraits< MeshConfig >::template SuperentityTraits< MeshEntity, DimensionTag::value >::storageEnabled >
 class MeshSuperentityAccessLayer;
 
 
@@ -28,12 +34,12 @@ template< typename MeshConfig,
 class MeshSuperentityAccess :
    public MeshSuperentityAccessLayer< MeshConfig,
                                          MeshEntity,
-                                         MeshDimensionsTag< MeshTraits< MeshConfig >::meshDimensions > >
+                                         MeshDimensionTag< MeshTraits< MeshConfig >::meshDimension > >
 {
    public:
       typedef MeshSuperentityAccessLayer< MeshConfig,
                                              MeshEntity,
-                                             MeshDimensionsTag< MeshTraits< MeshConfig >::meshDimensions > > BaseType;
+                                             MeshDimensionTag< MeshTraits< MeshConfig >::meshDimension > > BaseType;
  
       bool operator == ( const MeshSuperentityAccess< MeshConfig, MeshEntity>& a ) const { return true; } // TODO: fix
  
@@ -46,38 +52,38 @@ class MeshSuperentityAccess :
 
 template< typename MeshConfig,
           typename MeshEntity,
-          typename Dimensions >
+          typename Dimension >
 class MeshSuperentityAccessLayer< MeshConfig,
                                      MeshEntity,
-                                     Dimensions,
+                                     Dimension,
                                      true > :
-   public MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimensions::Decrement >
+   public MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimension::Decrement >
 {
-	typedef MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimensions::Decrement > BaseType;
+	typedef MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimension::Decrement > BaseType;
 
    public:
  
       typedef MeshTraits< MeshConfig >                                                             MeshTraitsType;
-      typedef typename MeshTraitsType::template SuperentityTraits< MeshEntity, Dimensions::value > SuperentityTraitsType;
+      typedef typename MeshTraitsType::template SuperentityTraits< MeshEntity, Dimension::value > SuperentityTraitsType;
       typedef typename MeshTraitsType::IdArrayAccessorType                                         IdArrayAccessorType;
       typedef typename SuperentityTraitsType::StorageNetworkType                                   StorageNetworkType;
       typedef typename SuperentityTraitsType::SuperentityAccessorType                              SuperentityAccessorType;
       //typedef typename StorageNetworkType::PortsType                            SuperentityAccessorType;
 
 	   using BaseType::superentityIds;
-	   IdArrayAccessorType superentityIds( Dimensions ) const { return m_superentityIndices; }
+	   IdArrayAccessorType superentityIds( Dimension ) const { return m_superentityIndices; }
 
 	   using BaseType::superentityIdsArray;
-	   IdArrayAccessorType &superentityIdsArray( Dimensions ) { return m_superentityIndices; }
+	   IdArrayAccessorType &superentityIdsArray( Dimension ) { return m_superentityIndices; }
  
       using BaseType::getSuperentityIndices;
-      const SuperentityAccessorType& getSuperentityIndices( Dimensions ) const
+      const SuperentityAccessorType& getSuperentityIndices( Dimension ) const
       {
          std::cerr << "###" << std::endl;
          return this->superentityIndices;
       }
  
-      SuperentityAccessorType& getSuperentityIndices( Dimensions )
+      SuperentityAccessorType& getSuperentityIndices( Dimension )
       {
          std::cerr << "######" << std::endl;
          return this->superentityIndices;
@@ -85,12 +91,12 @@ class MeshSuperentityAccessLayer< MeshConfig,
  
       void print( std::ostream& str ) const
       {
-         str << "Superentities with " << Dimensions::value << " dimensions are: " <<
+         str << "Superentities with " << Dimension::value << " dimensions are: " <<
             this->superentityIndices << std::endl;
          BaseType::print( str );
       }
  
-      //bool operator == ( const MeshSuperentityAccessLayer< MeshConfig, MeshEntity, Dimensions, tnlStorageTraits< true > >& l ) { return true; } // TODO: fix
+      //bool operator == ( const MeshSuperentityAccessLayer< MeshConfig, MeshEntity, Dimension, tnlStorageTraits< true > >& l ) { return true; } // TODO: fix
 
    private:
 	   IdArrayAccessorType m_superentityIndices;
@@ -101,12 +107,12 @@ class MeshSuperentityAccessLayer< MeshConfig,
 
 template< typename MeshConfig,
           typename MeshEntity,
-          typename Dimensions >
+          typename Dimension >
 class MeshSuperentityAccessLayer< MeshConfig,
                                      MeshEntity,
-                                     Dimensions,
+                                     Dimension,
                                      false > :
-   public MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimensions::Decrement >
+   public MeshSuperentityAccessLayer< MeshConfig, MeshEntity, typename Dimension::Decrement >
 {
 };
 
@@ -114,7 +120,7 @@ template< typename MeshConfig,
           typename MeshEntity >
 class MeshSuperentityAccessLayer< MeshConfig,
                                      MeshEntity,
-                                     MeshDimensionsTag< MeshEntity::dimensions >,
+                                     MeshDimensionTag< MeshEntity::dimensions >,
                                      false >
 {
    protected:
@@ -133,7 +139,7 @@ template< typename MeshConfig,
           typename MeshEntity >
 class MeshSuperentityAccessLayer< MeshConfig,
                                      MeshEntity,
-                                     MeshDimensionsTag< MeshEntity::dimensions >,
+                                     MeshDimensionTag< MeshEntity::dimensions >,
                                      true >
 {
    protected:
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccessor.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccessor.h
index 80eb5c0ce5dd7cd048fe430090d6e6c2fea8b84b..ebe8ee41940190935657615eef3b95419def2d41 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccessor.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityAccessor.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
diff --git a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
index f5fa7c10e45a808cd0d0c51ebf6525ac287ac2db..d02a1beafb69f6fbf1d86592c0dbc78f9dc4ce07 100644
--- a/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h
@@ -8,10 +8,16 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/File.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h>
 
@@ -20,9 +26,9 @@ namespace Meshes {
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag,
+          typename DimensionTag,
           bool SuperentityStorage =
-             MeshSuperentityTraits< MeshConfig, EntityTopology, DimensionsTag::value >::storageEnabled >
+             MeshSuperentityTraits< MeshConfig, EntityTopology, DimensionTag::value >::storageEnabled >
 class MeshSuperentityStorageLayer;
 
 template< typename MeshConfig,
@@ -30,22 +36,22 @@ template< typename MeshConfig,
 class MeshSuperentityStorageLayers
    : public MeshSuperentityStorageLayer< MeshConfig,
                                             EntityTopology,
-                                            MeshDimensionsTag< MeshTraits< MeshConfig >::meshDimensions > >
+                                            MeshDimensionTag< MeshTraits< MeshConfig >::meshDimension > >
 {
 };
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
-class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, true >
-   : public MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionsTag::Decrement >
+          typename DimensionTag >
+class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionTag, true >
+   : public MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionTag::Decrement >
 {
    typedef
-      MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionsTag::Decrement >  BaseType;
+      MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionTag::Decrement >  BaseType;
 
-   static const int Dimensions = DimensionsTag::value;
+   static const int Dimension = DimensionTag::value;
    typedef MeshTraits< MeshConfig >                                                          MeshTraitsType;
-   typedef typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimensions > SuperentityTraitsType;
+   typedef typename MeshTraitsType::template SuperentityTraits< EntityTopology, Dimension > SuperentityTraitsType;
 
    protected:
 
@@ -71,7 +77,7 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
 
     /*~MeshSuperentityStorageLayer()
     {
-       std::cerr << "      Destroying " << this->superentitiesIndices.getSize() << " superentities with "<< DimensionsTag::value << " dimensions." << std::endl;
+       std::cerr << "      Destroying " << this->superentitiesIndices.getSize() << " superentities with "<< DimensionTag::value << " dimensions." << std::endl;
        std::cerr << "         this->superentitiesIndices.getName() = " << this->superentitiesIndices.getName() << std::endl;
        std::cerr << "         this->sharedSuperentitiesIndices.getName() = " << this->sharedSuperentitiesIndices.getName() << std::endl;
     }*/
@@ -87,7 +93,7 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
     /****
      * Define setter/getter for the current level of the superentities
      */
-    bool setNumberOfSuperentities( DimensionsTag,
+    bool setNumberOfSuperentities( DimensionTag,
                                    const LocalIndexType size )
     {
        if( ! this->superentitiesIndices.setSize( size ) )
@@ -97,30 +103,30 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
        return true;
     }
 
-    LocalIndexType getNumberOfSuperentities( DimensionsTag ) const
+    LocalIndexType getNumberOfSuperentities( DimensionTag ) const
     {
        return this->superentitiesIndices.getSize();
     }
 
-    void setSuperentityIndex( DimensionsTag,
+    void setSuperentityIndex( DimensionTag,
                               const LocalIndexType localIndex,
                               const GlobalIndexType globalIndex )
     {
        this->superentitiesIndices[ localIndex ] = globalIndex;
     }
 
-    GlobalIndexType getSuperentityIndex( DimensionsTag,
+    GlobalIndexType getSuperentityIndex( DimensionTag,
                                          const LocalIndexType localIndex ) const
     {
        return this->superentitiesIndices[ localIndex ];
     }
 
-    AccessArrayType& getSuperentitiesIndices( DimensionsTag )
+    AccessArrayType& getSuperentitiesIndices( DimensionTag )
     {
        return this->sharedSuperentitiesIndices;
     }
 
-    const AccessArrayType& getSuperentitiesIndices( DimensionsTag ) const
+    const AccessArrayType& getSuperentitiesIndices( DimensionTag ) const
     {
        return this->sharedSuperentitiesIndices;
     }
@@ -130,7 +136,7 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
        if( ! BaseType::save( file ) ||
            ! this->superentitiesIndices.save( file ) )
        {
-          //cerr << "Saving of the entity superentities layer with " << DimensionsTag::value << " failed." << std::endl;
+          //cerr << "Saving of the entity superentities layer with " << DimensionTag::value << " failed." << std::endl;
           return false;
        }
        return true;
@@ -141,7 +147,7 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
        if( ! BaseType::load( file ) ||
            ! this->superentitiesIndices.load( file ) )
        {
-          //cerr << "Loading of the entity superentities layer with " << DimensionsTag::value << " failed." << std::endl;
+          //cerr << "Loading of the entity superentities layer with " << DimensionTag::value << " failed." << std::endl;
           return false;
        }
        return true;
@@ -150,7 +156,7 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
     void print( std::ostream& str ) const
     {
        BaseType::print( str );
-       str << std::endl << "\t Superentities with " << DimensionsTag::value << " dimensions are: " << this->superentitiesIndices << ".";
+       str << std::endl << "\t Superentities with " << DimensionTag::value << " dimensions are: " << this->superentitiesIndices << ".";
     }
 
     bool operator==( const MeshSuperentityStorageLayer& layer  ) const
@@ -171,13 +177,13 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
    public:
  
       using BaseType::superentityIdsArray;
-      typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionsTag )
+      typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionTag )
       {
          return this->superentitiesIndices;
       }
  
       using BaseType::getStorageNetwork;
-      StorageNetworkType& getStorageNetwork( DimensionsTag )
+      StorageNetworkType& getStorageNetwork( DimensionTag )
       {
          return this->storageNetwork;
       }
@@ -185,9 +191,9 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, tr
 
 template< typename MeshConfig,
           typename EntityTopology,
-          typename DimensionsTag >
-class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, false >
-   : public MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionsTag::Decrement >
+          typename DimensionTag >
+class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionTag, false >
+   : public MeshSuperentityStorageLayer< MeshConfig, EntityTopology, typename DimensionTag::Decrement >
 {
    public:
 
@@ -195,16 +201,16 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, DimensionsTag, fa
 
 template< typename MeshConfig,
           typename EntityTopology >
-class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, MeshDimensionsTag< EntityTopology::dimensions >, false >
+class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, MeshDimensionTag< EntityTopology::dimensions >, false >
 {
-   static const int Dimensions = EntityTopology::dimensions;
-   typedef MeshDimensionsTag< EntityTopology::dimensions >        DimensionsTag;
+   static const int Dimension = EntityTopology::dimensions;
+   typedef MeshDimensionTag< EntityTopology::dimensions >        DimensionTag;
 
-   typedef MeshSuperentityTraits< MeshConfig, EntityTopology, Dimensions >      SuperentityTraits;
+   typedef MeshSuperentityTraits< MeshConfig, EntityTopology, Dimension >      SuperentityTraits;
 
    typedef MeshSuperentityStorageLayer< MeshConfig,
                                            EntityTopology,
-                                           DimensionsTag,
+                                           DimensionTag,
                                            false > ThisType;
 
    protected:
@@ -218,12 +224,12 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, MeshDimensionsTag
    /****
     * These methods are due to 'using BaseType::...;' in the derived classes.
     */
-   bool setNumberOfSuperentities( DimensionsTag,
+   bool setNumberOfSuperentities( DimensionTag,
                                    const LocalIndexType size );
-   LocalIndexType getNumberOfSuperentities( DimensionsTag ) const;
-   GlobalIndexType getSuperentityIndex( DimensionsTag,
+   LocalIndexType getNumberOfSuperentities( DimensionTag ) const;
+   GlobalIndexType getSuperentityIndex( DimensionTag,
                                         const LocalIndexType localIndex ){}
-   void setSuperentityIndex( DimensionsTag,
+   void setSuperentityIndex( DimensionTag,
                              const LocalIndexType localIndex,
                              const GlobalIndexType globalIndex ) {}
 
@@ -248,15 +254,15 @@ class MeshSuperentityStorageLayer< MeshConfig, EntityTopology, MeshDimensionsTag
       return true;
    }
  
-   typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionsTag )
+   typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionTag )
    {
-      Assert( false, );
+      TNL_ASSERT( false, );
       //return this->superentitiesIndices;
    }
 
-   StorageNetworkType& getStorageNetwork( DimensionsTag )
+   StorageNetworkType& getStorageNetwork( DimensionTag )
    {
-      Assert( false, );
+      TNL_ASSERT( false, );
      //return this->storageNetwork;
    }
 
@@ -266,18 +272,18 @@ template< typename MeshConfig,
           typename EntityTopology >
 class MeshSuperentityStorageLayer< MeshConfig,
                                       EntityTopology,
-                                      MeshDimensionsTag< EntityTopology::dimensions >,
+                                      MeshDimensionTag< EntityTopology::dimensions >,
                                       true >
 {
-   static const int Dimensions = EntityTopology::dimensions;
-   typedef MeshDimensionsTag< Dimensions >                          DimensionsTag;
+   static const int Dimension = EntityTopology::dimensions;
+   typedef MeshDimensionTag< Dimension >                          DimensionTag;
 
    typedef MeshSuperentityTraits< MeshConfig,
                                      EntityTopology,
-                                     Dimensions >               SuperentityTraits;
+                                     Dimension >               SuperentityTraits;
    typedef MeshSuperentityStorageLayer< MeshConfig,
                                            EntityTopology,
-                                           DimensionsTag,
+                                           DimensionTag,
                                            true > ThisType;
 
    protected:
@@ -291,12 +297,12 @@ class MeshSuperentityStorageLayer< MeshConfig,
    /****
     * These methods are due to 'using BaseType::...;' in the derived classes.
     */
-   bool setNumberOfSuperentities( DimensionsTag,
+   bool setNumberOfSuperentities( DimensionTag,
                                    const LocalIndexType size );
-   LocalIndexType getNumberOfSuperentities( DimensionsTag ) const;
-   GlobalIndexType getSuperentityIndex( DimensionsTag,
+   LocalIndexType getNumberOfSuperentities( DimensionTag ) const;
+   GlobalIndexType getSuperentityIndex( DimensionTag,
                                         const LocalIndexType localIndex ){}
-   void setSuperentityIndex( DimensionsTag,
+   void setSuperentityIndex( DimensionTag,
                              const LocalIndexType localIndex,
                              const GlobalIndexType globalIndex ) {}
 
@@ -321,15 +327,15 @@ class MeshSuperentityStorageLayer< MeshConfig,
       return true;
    }
  
-   typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionsTag )
+   typename MeshTraits< MeshConfig >::GlobalIdArrayType& superentityIdsArray( DimensionTag )
    {
-      Assert( false, );
+      TNL_ASSERT( false, );
       //return this->superentitiesIndices;
    }
 
-   StorageNetworkType& getStorageNetwork( DimensionsTag )
+   StorageNetworkType& getStorageNetwork( DimensionTag )
    {
-      Assert( false, );
+      TNL_ASSERT( false, );
       //return this->storageNetwork;
    }
 
diff --git a/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt b/src/TNL/Meshes/MeshDetails/traits/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
index b6d31f6a395faf9b746958e1cf1c9df28c2c2201..c8c8be6b9a5c45dea478cacfa349d4525d82aad9 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/StaticVector.h>
@@ -28,26 +34,26 @@ template< typename MeshConfig, typename EntityTopology > class MeshEntitySeedKey
 template< typename MeshConfig, typename EntityTopology > class MeshEntityReferenceOrientation;
 
 template< typename MeshConfig,
-          typename DimensionsTag,
-          typename SuperDimensionsTag = MeshDimensionsTag< MeshConfig::meshDimensions > >
+          typename DimensionTag,
+          typename SuperDimensionTag = MeshDimensionTag< MeshConfig::meshDimension > >
 class MeshEntityOrientationNeeded
 {
-	static_assert( 0 <= DimensionsTag::value && DimensionsTag::value < MeshConfig::CellTopology::dimensions, "invalid dimensions" );
-	static_assert( DimensionsTag::value < SuperDimensionsTag::value && SuperDimensionsTag::value <= MeshConfig::CellTopology::dimensions, "invalid superentity dimensions");
+	static_assert( 0 <= DimensionTag::value && DimensionTag::value < MeshConfig::CellTopology::dimensions, "invalid dimensions" );
+	static_assert( DimensionTag::value < SuperDimensionTag::value && SuperDimensionTag::value <= MeshConfig::CellTopology::dimensions, "invalid superentity dimension");
 
-	typedef typename MeshTraits< MeshConfig >::template EntityTraits< SuperDimensionsTag::value >::EntityTopology SuperentityTopology;
+	typedef typename MeshTraits< MeshConfig >::template EntityTraits< SuperDimensionTag::value >::EntityTopology SuperentityTopology;
 
-	static const bool previousSuperDimensionsValue = MeshEntityOrientationNeeded< MeshConfig, DimensionsTag, typename SuperDimensionsTag::Decrement >::value;
-	static const bool thisSuperDimensionsValue = MeshTraits< MeshConfig >::template SubentityTraits< SuperentityTopology, DimensionsTag::value >::orientationEnabled;
+	static const bool previousSuperDimensionValue = MeshEntityOrientationNeeded< MeshConfig, DimensionTag, typename SuperDimensionTag::Decrement >::value;
+	static const bool thisSuperDimensionValue = MeshTraits< MeshConfig >::template SubentityTraits< SuperentityTopology, DimensionTag::value >::orientationEnabled;
 
    public:
-      static const bool value = ( previousSuperDimensionsValue || thisSuperDimensionsValue );
+      static const bool value = ( previousSuperDimensionValue || thisSuperDimensionValue );
 };
 
-template< typename MeshConfig, typename DimensionsTag >
-class MeshEntityOrientationNeeded< MeshConfig, DimensionsTag, DimensionsTag >
+template< typename MeshConfig, typename DimensionTag >
+class MeshEntityOrientationNeeded< MeshConfig, DimensionTag, DimensionTag >
 {
-	static_assert( 0 <= DimensionsTag::value && DimensionsTag::value <= MeshConfig::CellTopology::dimensions, "invalid dimensions" );
+	static_assert( 0 <= DimensionTag::value && DimensionTag::value <= MeshConfig::CellTopology::dimensions, "invalid dimensions" );
 
    public:
       static const bool value = false;
@@ -55,17 +61,17 @@ class MeshEntityOrientationNeeded< MeshConfig, DimensionsTag, DimensionsTag >
 
 
 template< typename MeshConfig,
-          int Dimensions >
+          int Dimension >
 class MeshEntityTraits
 {
    public:
 
-      static const bool storageEnabled = MeshConfig::entityStorage( Dimensions );
-      static const bool orientationNeeded = MeshEntityOrientationNeeded< MeshConfig, MeshDimensionsTag< Dimensions > >::value;
+      static const bool storageEnabled = MeshConfig::entityStorage( Dimension );
+      static const bool orientationNeeded = MeshEntityOrientationNeeded< MeshConfig, MeshDimensionTag< Dimension > >::value;
 
       typedef typename MeshConfig::GlobalIndexType                                 GlobalIndexType;
       typedef typename MeshConfig::LocalIndexType                                  LocalIndexType;
-      typedef typename MeshEntityTopology< MeshConfig, Dimensions >::Topology   EntityTopology;
+      typedef typename MeshEntityTopology< MeshConfig, Dimension >::Topology   EntityTopology;
  
       typedef MeshEntity< MeshConfig, EntityTopology >                          EntityType;
       typedef MeshEntitySeed< MeshConfig, EntityTopology >                      SeedType;
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h
index 9ff9103bf4a6cf02920b09e0cbb2067f741bd080..cbdd144932f6509f14082ea4d7981ba3e3ee47bf 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshSubentityTraits.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/StaticArray.h>
@@ -23,16 +29,16 @@ template< typename MeshConfig, typename EntityTopology > class MeshEntityOrienta
 
 template< typename MeshConfig,
           typename EntityTopology,
-          int Dimensions >
+          int Dimension >
 class MeshSubentityTraits
 {
    public:
-      static const bool storageEnabled = MeshConfig::subentityStorage( EntityTopology(), Dimensions );
-      static const bool orientationEnabled = MeshConfig::subentityOrientationStorage( EntityTopology(), Dimensions );
+      static const bool storageEnabled = MeshConfig::subentityStorage( EntityTopology(), Dimension );
+      static const bool orientationEnabled = MeshConfig::subentityOrientationStorage( EntityTopology(), Dimension );
 
       typedef typename MeshConfig::GlobalIndexType                                GlobalIndexType;
       typedef typename MeshConfig::LocalIndexType                                 LocalIndexType;
-      typedef MeshSubtopology< EntityTopology, Dimensions >                    Subtopology;
+      typedef MeshSubtopology< EntityTopology, Dimension >                    Subtopology;
       typedef typename Subtopology::Topology                                      SubentityTopology;
       typedef MeshEntity< MeshConfig, SubentityTopology >                      SubentityType;
       typedef MeshEntitySeed< MeshConfig, SubentityTopology >                  Seed;
@@ -52,16 +58,16 @@ class MeshSubentityTraits
       typedef Containers::StaticArray< count, LocalIndexType >               IdPermutationArrayType;
 
       template< LocalIndexType subentityIndex,
-                LocalIndexType subentityVertexIndex >
-      struct Vertex
+                LocalIndexType subentityPointIndex >
+      struct Point
       {
-         enum { index = tnlSubentityVertex< EntityTopology,
+         enum { index = tnlSubentityPoint< EntityTopology,
                                             SubentityTopology,
                                             subentityIndex,
-                                            subentityVertexIndex>::index };
+                                            subentityPointIndex>::index };
       };
 
-      static_assert( EntityTopology::dimensions > Dimensions, "You try to create subentities traits where subentity dimensions are not smaller than the entity dimensions." );
+      static_assert( EntityTopology::dimensions > Dimension, "You try to create subentities traits where subentity dimension are not smaller than the entity dimension." );
 };
 
 } // namespace Meshes
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
index 37c0ff6caaf4ee377b6dda679cbe93d40c844043..b4e816399673a2a71ddcc46bac1e273923afdea8 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshSuperentityTraits.h
@@ -8,11 +8,17 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/Array.h>
 #include <TNL/Containers/ConstSharedArray.h>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/Meshes/MeshEntity.h>
 #include <TNL/Meshes/MeshConfigBase.h>
 #include <TNL/Meshes/Topologies/MeshEntityTopology.h>
@@ -25,7 +31,7 @@ namespace Meshes {
 
 template< typename MeshConfig,
           typename EntityTopology,
-          int Dimensions >
+          int Dimension >
 class MeshSuperentityTraits
 {
    public:
@@ -34,10 +40,10 @@ class MeshSuperentityTraits
    typedef typename MeshConfig::LocalIndexType                               LocalIndexType;
 
 
-   static const bool storageEnabled = MeshConfig::template superentityStorage< EntityTopology >( EntityTopology(), Dimensions );
+   static const bool storageEnabled = MeshConfig::template superentityStorage< EntityTopology >( EntityTopology(), Dimension );
    //typedef tnlStorageTraits< storageEnabled >                               SuperentityStorageTag;
    typedef MeshEntity< MeshConfig, EntityTopology >                            EntityType;
-   typedef MeshEntityTraits< MeshConfig, Dimensions >                     EntityTraits;
+   typedef MeshEntityTraits< MeshConfig, Dimension >                     EntityTraits;
    typedef typename EntityTraits::EntityTopology                             SuperentityTopology;
    typedef typename EntityTraits::EntityType                                 SuperentityType;
 
@@ -60,7 +66,7 @@ class MeshSuperentityTraits
    /****
     * This is used by the mesh initializer.
     */
-   typedef List< GlobalIndexType >                                       GrowableContainerType;
+   typedef Containers::List< GlobalIndexType >                                       GrowableContainerType;
 
 };
 
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
index 8bfca4c14c22ba0ee99ad6a0a80a48bde7446303..4cd115593b534804fd9815f466214388f6556cfa 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
@@ -8,13 +8,19 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/StaticVector.h>
 #include <TNL/Containers/Array.h>
 #include <TNL/Containers/SharedArray.h>
 #include <TNL/Containers/ConstSharedArray.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 
 namespace TNL {
 namespace Meshes {
@@ -22,9 +28,9 @@ namespace Meshes {
 struct MeshVertexTopology;
 template< typename MeshConfig, typename EntityTopology > class MeshEntity;
 template< typename MeshConfig, typename EntityTopology > class MeshEntitySeed;
-template< typename MeshConfig, int Dimensions > class MeshEntityTraits;
-template< typename MeshConfig, typename MeshEntity, int SubDimensions > class MeshSubentityTraits;
-template< typename MeshConfig, typename MeshEntity, int SuperDimensions > class MeshSuperentityTraits;
+template< typename MeshConfig, int Dimension > class MeshEntityTraits;
+template< typename MeshConfig, typename MeshEntity, int SubDimension > class MeshSubentityTraits;
+template< typename MeshConfig, typename MeshEntity, int SuperDimension > class MeshSuperentityTraits;
 
 template< typename MeshConfig,
           typename Device = Devices::Host >
@@ -32,8 +38,8 @@ class MeshTraits
 {
    public:
  
-      static const int meshDimensions = MeshConfig::CellTopology::dimensions;
-      static const int worldDimensions = MeshConfig::worldDimensions;
+      static const int meshDimension = MeshConfig::CellTopology::dimensions;
+      static const int worldDimension = MeshConfig::worldDimension;
 
       typedef Device                                                               DeviceType;
       typedef typename MeshConfig::GlobalIndexType                                 GlobalIndexType;
@@ -42,7 +48,7 @@ class MeshTraits
       typedef typename MeshConfig::CellTopology                                    CellTopology;
       typedef MeshEntity< MeshConfig, CellTopology >                            CellType;
       typedef MeshEntity< MeshConfig, MeshVertexTopology >                   VertexType;
-      typedef Containers::StaticVector< worldDimensions, typename MeshConfig::RealType >    PointType;
+      typedef Containers::StaticVector< worldDimension, typename MeshConfig::RealType >    PointType;
       typedef MeshEntitySeed< MeshConfig, CellTopology >                        CellSeedType;
  
       typedef Containers::Array< PointType, Devices::Host, GlobalIndexType >                  PointArrayType;
@@ -51,17 +57,17 @@ class MeshTraits
       typedef Containers::tnlConstSharedArray< GlobalIndexType, Devices::Host, LocalIndexType >  IdArrayAccessorType;
       typedef Containers::tnlConstSharedArray< LocalIndexType, Devices::Host, LocalIndexType >   IdPermutationArrayAccessorType;
  
-      template< int Dimensions > using EntityTraits =
-         MeshEntityTraits< MeshConfig, Dimensions >;
+      template< int Dimension > using EntityTraits =
+         MeshEntityTraits< MeshConfig, Dimension >;
  
-      template< typename EntityTopology, int SubDimensions > using SubentityTraits =
-         MeshSubentityTraits< MeshConfig, EntityTopology, SubDimensions >;
+      template< typename EntityTopology, int SubDimension > using SubentityTraits =
+         MeshSubentityTraits< MeshConfig, EntityTopology, SubDimension >;
  
-      template< typename EntityTopology, int SuperDimensions > using SuperentityTraits =
-         MeshSuperentityTraits< MeshConfig, EntityTopology, SuperDimensions >;
+      template< typename EntityTopology, int SuperDimension > using SuperentityTraits =
+         MeshSuperentityTraits< MeshConfig, EntityTopology, SuperDimension >;
  
  
-      typedef MeshDimensionsTag< meshDimensions >                                   DimensionsTag;
+      typedef MeshDimensionTag< meshDimension >                                   DimensionTag;
 
 };
 
diff --git a/src/TNL/Meshes/MeshDimensionsTag.h b/src/TNL/Meshes/MeshDimensionTag.h
similarity index 75%
rename from src/TNL/Meshes/MeshDimensionsTag.h
rename to src/TNL/Meshes/MeshDimensionTag.h
index 3f29b03ae56db4645e3b24480a99b4ef33a7f24d..10dbcdaf71605a627f29154074dd1e76d0cc0df9 100644
--- a/src/TNL/Meshes/MeshDimensionsTag.h
+++ b/src/TNL/Meshes/MeshDimensionTag.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          MeshDimensionsTag.h  -  description
+                          MeshDimensionTag.h  -  description
                              -------------------
     begin                : Feb 11, 2014
     copyright            : (C) 2014 by Tomas Oberhuber
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Assert.h>
@@ -26,25 +32,25 @@ namespace Meshes {
  * Therefore one cannot specialize the mesh layers just by integers saying the mesh
  * layer dimensions but instead this tag must be used. This makes the code more difficult
  * to read and we would like to avoid it if it is possible sometime.
- * On the other hand, MeshDimensionsTag is also used for method overloading when
+ * On the other hand, MeshDimensionTag is also used for method overloading when
  * asking for different mesh entities. In this case it makes sense and it cannot be
  * replaced.
  */
 
-template< int Dimensions >
-class MeshDimensionsTag
+template< int Dimension >
+class MeshDimensionTag
 {
    public:
 
-      static const int value = Dimensions;
+      static const int value = Dimension;
 
-      typedef MeshDimensionsTag< Dimensions - 1 > Decrement;
+      typedef MeshDimensionTag< Dimension - 1 > Decrement;
 
       static_assert( value >= 0, "The value of the dimensions cannot be negative." );
 };
 
 template<>
-class MeshDimensionsTag< 0 >
+class MeshDimensionTag< 0 >
 {
    public:
  
diff --git a/src/TNL/Meshes/MeshEntity.h b/src/TNL/Meshes/MeshEntity.h
index 9f188a8b316f2e9e1284d507b53a53e8828ea952..0aedeb356d1074741efcc6ebaef1bb6a0334b261 100644
--- a/src/TNL/Meshes/MeshEntity.h
+++ b/src/TNL/Meshes/MeshEntity.h
@@ -8,13 +8,19 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/File.h>
 #include <TNL/Containers/DynamicTypeTag.h>
 #include <TNL/Meshes/MeshDetails/MeshEntityId.h>
 #include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
-#include <TNL/Meshes/MeshDimensionsTag.h>
+#include <TNL/Meshes/MeshDimensionTag.h>
 #include <TNL/Meshes/Topologies/MeshVertexTopology.h>
 #include <TNL/Meshes/MeshDetails/layers/MeshSubentityStorageLayer.h>
 #include <TNL/Meshes/MeshDetails/layers/MeshSuperentityStorageLayer.h>
@@ -47,8 +53,8 @@ class MeshEntity
       template< int Subdimensions > using SubentityTraits =
       typename MeshTraitsType::template SubentityTraits< EntityTopology, Subdimensions >;
  
-      template< int SuperDimensions > using SuperentityTraits =
-      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperDimensions >;
+      template< int SuperDimension > using SuperentityTraits =
+      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperDimension >;
  
       MeshEntity( const SeedType& entitySeed );
 
@@ -68,7 +74,7 @@ class MeshEntity
 
       bool operator==( const MeshEntity& entity ) const;
  
-      constexpr int getEntityDimensions() const;
+      constexpr int getEntityDimension() const;
 
       /****
        * Subentities
@@ -91,17 +97,17 @@ class MeshEntity
       /****
        * Superentities
        */
-      template< int SuperDimensions >
+      template< int SuperDimension >
       LocalIndexType getNumberOfSuperentities() const;
 
-      template< int SuperDimensions >
+      template< int SuperDimension >
       GlobalIndexType getSuperentityIndex( const LocalIndexType localIndex ) const;
 
-      template< int SuperDimensions >
-         typename SuperentityTraits< SuperDimensions >::AccessArrayType& getSuperentitiesIndices();
+      template< int SuperDimension >
+         typename SuperentityTraits< SuperDimension >::AccessArrayType& getSuperentitiesIndices();
 
-      template< int SuperDimensions >
-         const typename SuperentityTraits< SuperDimensions >::AccessArrayType& getSuperentitiesIndices() const;
+      template< int SuperDimension >
+         const typename SuperentityTraits< SuperDimension >::AccessArrayType& getSuperentitiesIndices() const;
 
       /****
        * Vertices
@@ -114,7 +120,7 @@ class MeshEntity
 
       const typename SubentityTraits< 0 >::AccessArrayType& getVerticesIndices() const;
 
-      template< int Dimensions >
+      template< int Dimension >
       IdPermutationArrayAccessorType subentityOrientation( LocalIndexType index ) const;
  
    protected:
@@ -162,8 +168,8 @@ class MeshEntity< MeshConfig, MeshVertexTopology >
       typedef typename MeshTraitsType::IdPermutationArrayAccessorType IdPermutationArrayAccessorType;
       typedef MeshEntitySeed< MeshConfig, EntityTopology >     SeedType;
  
-      template< int SuperDimensions > using SuperentityTraits =
-      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperDimensions >;
+      template< int SuperDimension > using SuperentityTraits =
+      typename MeshTraitsType::template SuperentityTraits< EntityTopology, SuperDimension >;
 
       static String getType();
 
@@ -179,7 +185,7 @@ class MeshEntity< MeshConfig, MeshVertexTopology >
 
       bool operator==( const MeshEntity& entity ) const;
  
-      constexpr int getEntityDimensions() const;
+      constexpr int getEntityDimension() const;
 
       template< int Superdimensions > LocalIndexType getNumberOfSuperentities() const;
 
@@ -189,7 +195,7 @@ class MeshEntity< MeshConfig, MeshVertexTopology >
       template< int Superdimensions >
          const typename SuperentityTraits< Superdimensions >::AccessArrayType& getSuperentitiesIndeces() const;
 
-      template< int Dimensions >
+      template< int Dimension >
       GlobalIndexType getSuperentityIndex( const LocalIndexType localIndex ) const;
 
       /****
diff --git a/src/TNL/Meshes/Topologies/CMakeLists.txt b/src/TNL/Meshes/Topologies/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Meshes/Topologies/MeshEdgeTopology.h b/src/TNL/Meshes/Topologies/MeshEdgeTopology.h
index 1edb84a262f5d429088ed0dbb2b41807c7ed8c1f..34e8778baa434e444a50e01068d06812e44992d1 100644
--- a/src/TNL/Meshes/Topologies/MeshEdgeTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshEdgeTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Topologies/MeshEntityTopology.h>
diff --git a/src/TNL/Meshes/Topologies/MeshEntityTopology.h b/src/TNL/Meshes/Topologies/MeshEntityTopology.h
index 306e138d1b84f4aca72e760f6ba858c88593f7d1..589bec5db38d2cc7a406b8abd3092251f8247628 100644
--- a/src/TNL/Meshes/Topologies/MeshEntityTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshEntityTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
@@ -27,13 +33,13 @@ struct tnlSubentityVertex;
 
 
 template< typename MeshConfig,
-          int Dimensions >
+          int Dimension >
 class MeshEntityTopology
 {
    public:
 
    typedef typename MeshSubtopology< typename MeshConfig::CellTopology,
-                                        Dimensions >::Topology Topology;
+                                        Dimension >::Topology Topology;
 };
 
 template< typename MeshConfig >
diff --git a/src/TNL/Meshes/Topologies/MeshHexahedronTopology.h b/src/TNL/Meshes/Topologies/MeshHexahedronTopology.h
index 7a3e08a9991d2ed60d4ff34fccf72fd0e96e41ae..4dc1ff3acae2a5579885bf00963150d86cc52844 100644
--- a/src/TNL/Meshes/Topologies/MeshHexahedronTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshHexahedronTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Topologies/MeshQuadrilateralTopology.h>
diff --git a/src/TNL/Meshes/Topologies/MeshQuadrilateralTopology.h b/src/TNL/Meshes/Topologies/MeshQuadrilateralTopology.h
index bb650528beca40aa35d9a877cb6590dd6ede8000..4dd844e4c9c0b3bd195c9f3387f8bbfa7d3557e2 100644
--- a/src/TNL/Meshes/Topologies/MeshQuadrilateralTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshQuadrilateralTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Topologies/MeshEdgeTopology.h>
diff --git a/src/TNL/Meshes/Topologies/MeshSimplexTopology.h b/src/TNL/Meshes/Topologies/MeshSimplexTopology.h
index e331db4d945b2242607968784e32ca99fcdad7a2..2120a71c7a120ab996e4b68777bcea99bfad5e22 100644
--- a/src/TNL/Meshes/Topologies/MeshSimplexTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshSimplexTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 
 #pragma once
 
diff --git a/src/TNL/Meshes/Topologies/MeshSubtopology.h b/src/TNL/Meshes/Topologies/MeshSubtopology.h
index 8f522299dead491890eb200d283e55962cf20e3f..df9d813302025b4f6373f6ff4dc2f032b72a96ba 100644
--- a/src/TNL/Meshes/Topologies/MeshSubtopology.h
+++ b/src/TNL/Meshes/Topologies/MeshSubtopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
diff --git a/src/TNL/Meshes/Topologies/MeshTetrahedronTopology.h b/src/TNL/Meshes/Topologies/MeshTetrahedronTopology.h
index fc881e6d79c5581ac5595804a80485d55d7a58c8..4f0067c255af28cf33d2dc4c5140053dbc8c8052 100644
--- a/src/TNL/Meshes/Topologies/MeshTetrahedronTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshTetrahedronTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Topologies/MeshTriangleTopology.h>
diff --git a/src/TNL/Meshes/Topologies/MeshTriangleTopology.h b/src/TNL/Meshes/Topologies/MeshTriangleTopology.h
index 4b693014675108b573fe2147f5dbf35c23c90447..0305c4355cc289548bf8fe3381f9fd08c71b513a 100644
--- a/src/TNL/Meshes/Topologies/MeshTriangleTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshTriangleTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Meshes/Topologies/MeshEdgeTopology.h>
diff --git a/src/TNL/Meshes/Topologies/MeshVertexTopology.h b/src/TNL/Meshes/Topologies/MeshVertexTopology.h
index 4a8e48b67ebb29770fefcae35dc061368524cff0..5c70978f74687cf8999dd91b1ae811d1e8db9410 100644
--- a/src/TNL/Meshes/Topologies/MeshVertexTopology.h
+++ b/src/TNL/Meshes/Topologies/MeshVertexTopology.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Zabka Vitezslav, zabkav@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
diff --git a/src/TNL/Meshes/Traverser.h b/src/TNL/Meshes/Traverser.h
index 3350d7b1b16af58515c9b1e662242987a05fcca9..c9c647cd7314d800c4a56739945284530945b575 100644
--- a/src/TNL/Meshes/Traverser.h
+++ b/src/TNL/Meshes/Traverser.h
@@ -15,7 +15,7 @@ namespace Meshes {
 
 template< typename Mesh,
           typename MeshEntity,
-          int EntitiesDimensions = MeshEntity::entityDimensions >
+          int EntitiesDimension = MeshEntity::getEntityDimension() >
 class Traverser{};
 
 } // namespace Meshes
@@ -23,4 +23,4 @@ class Traverser{};
 
 #include <TNL/Meshes/GridDetails/Traverser_Grid1D.h>
 #include <TNL/Meshes/GridDetails/Traverser_Grid2D.h>
-#include <TNL/Meshes/GridDetails/Traverser_Grid3D.h>
\ No newline at end of file
+#include <TNL/Meshes/GridDetails/Traverser_Grid3D.h>
diff --git a/src/TNL/Object.cpp b/src/TNL/Object.cpp
index 06a819137a4f1f9bcbe3603263a9fd2762a317e0..b4f364139de556ce410526f1bf94e1e12b4d8e41 100644
--- a/src/TNL/Object.cpp
+++ b/src/TNL/Object.cpp
@@ -10,8 +10,6 @@
 
 #include <TNL/Object.h>
 #include <TNL/Assert.h>
-#include <TNL/File.h>
-#include <TNL/List.h>
 #include <iostream>
 #include <fstream>
 #include <cstring>
@@ -48,11 +46,7 @@ String Object :: getSerializationTypeVirtual() const
 
 bool Object :: save( File& file ) const
 {
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< const char, Devices::Host, int >( magic_number, strlen( magic_number ) ) )
-#else
    if( ! file. write( magic_number, strlen( magic_number ) ) )
-#endif
       return false;
    if( ! this->getSerializationTypeVirtual().save( file ) ) return false;
    return true;
@@ -82,55 +76,34 @@ bool Object :: boundLoad( File& file )
 bool Object :: save( const String& fileName ) const
 {
    File file;
-   if( ! file. open( fileName, tnlWriteMode ) )
+   if( ! file. open( fileName, IOMode::write ) )
    {
-      std::cerr << "I am not bale to open the file " << fileName << " for writing." << std::endl;
+      std::cerr << "I am not able to open the file " << fileName << " for writing." << std::endl;
       return false;
    }
-   if( ! this->save( file ) )
-      return false;
-   if( ! file. close() )
-   {
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-      return false;
-   }
-   return true;
+   return this->save( file );
 }
 
 bool Object :: load( const String& fileName )
 {
    File file;
-   if( ! file. open( fileName, tnlReadMode ) )
+   if( ! file. open( fileName, IOMode::read ) )
    {
-      std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl;
+      std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl;
       return false;
    }
-   if( ! this->load( file ) )
-      return false;
-   if( ! file. close() )
-   {
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-      return false;
-   }
-   return true;
+   return this->load( file );
 }
 
 bool Object :: boundLoad( const String& fileName )
 {
    File file;
-   if( ! file. open( fileName, tnlReadMode ) )
+   if( ! file. open( fileName, IOMode::read ) )
    {
-      std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl;
+      std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl;
       return false;
    }
-   if( ! this->boundLoad( file ) )
-      return false;
-   if( ! file. close() )
-   {
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-      return false;
-   }
-   return true;
+   return this->boundLoad( file );
 }
 
 void Object::setDeprecatedReadMode()
@@ -142,36 +115,38 @@ void Object::setDeprecatedReadMode()
 bool getObjectType( File& file, String& type )
 {
    char mn[ 10 ];
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< char, Devices::Host, int >( mn, strlen( magic_number ) ) )
-#else
    if( ! file. read( mn, strlen( magic_number ) ) )
-#endif
    {
       std::cerr << "Unable to read file " << file. getFileName() << " ... " << std::endl;
       return false;
    }
    if( strncmp( mn, magic_number, 5 ) != 0 &&
-       strncmp( mn, "SIM33", 5 ) != 0 ) return false;
-   if( ! type. load( file ) ) return false;
+       strncmp( mn, "SIM33", 5 ) != 0 )
+   {
+       std::cout << "Not a TNL file (wrong magic number)." << std::endl;
+       return false;
+   }
+   if( ! type. load( file ) )
+   {
+       std::cerr << "Cannot load the object type." << std::endl;
+       return false;
+   }
    return true;
 }
 
 bool getObjectType( const String& fileName, String& type )
 {
    File binaryFile;
-   if( ! binaryFile. open( fileName, tnlReadMode ) )
+   if( ! binaryFile. open( fileName, IOMode::read ) )
    {
       std::cerr << "I am not able to open the file " << fileName << " for detecting the object inside!" << std::endl;
       return false;
    }
-   bool ret_val = getObjectType( binaryFile, type );
-   binaryFile. close();
-   return ret_val;
+   return getObjectType( binaryFile, type );
 }
 
 bool parseObjectType( const String& objectType,
-                      List< String >& parsedObjectType )
+                      Containers::List< String >& parsedObjectType )
 {
    parsedObjectType.reset();
    int objectTypeLength = objectType. getLength();
@@ -191,7 +166,7 @@ bool parseObjectType( const String& objectType,
 
    /****
     * Now, we will extract the parameters.
-    * Each parameter can be template, so we must compute and pair
+    * Each parameter can be template, so we must count and pair
     * '<' with '>'.
     */
    int templateBrackets( 0 );
@@ -203,13 +178,12 @@ bool parseObjectType( const String& objectType,
          templateBrackets ++;
       if( ! templateBrackets )
       {
-         if( objectType[ i ] == ' ' ||
-             objectType[ i ] == ',' ||
+         if( objectType[ i ] == ',' ||
              objectType[ i ] == '>' )
          {
             if( buffer != "" )
             {
-               if( ! parsedObjectType. Append( buffer ) )
+               if( ! parsedObjectType. Append( buffer.strip( ' ' ) ) )
                   return false;
                buffer. setString( "" );
             }
diff --git a/src/TNL/Object.h b/src/TNL/Object.h
index d05c7595a4a9ee0eaa11be299440a1d247122e22..932361354be5778e661e140ed2dfa72145520447 100644
--- a/src/TNL/Object.h
+++ b/src/TNL/Object.h
@@ -10,15 +10,13 @@
 
 #pragma once
 
-#include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/CudaCallable.h>
 #include <TNL/String.h>
-
+#include <TNL/File.h>
+#include <TNL/Containers/List.h>
 
 namespace TNL {
 
-class File;
-template< class T > class List;
-
 //! This is basic class for all 'large' objects like matrices, meshes, grids, solvers etc.
 /*!
  *  Objects like numerical grids, meshes, matrices large vectors etc.
@@ -35,8 +33,10 @@ class Object
    public:
 
       //! Basic constructor
+#ifndef HAVE_MIC
       __cuda_callable__
       Object() : deprecatedReadMode( false ) {};
+#endif
 
       /****
        * Type getter. This returns the type in C++ style - for example the returned value
@@ -77,8 +77,9 @@ class Object
       // FIXME: __cuda_callable__ would have to be added to every overriding destructor,
       // even if the object's constructor is not __cuda_callable__
       //   __cuda_callable__
+#ifndef HAVE_MIC
       virtual ~Object(){};
-   
+#endif
    
    protected:
       
@@ -92,6 +93,6 @@ bool getObjectType( File& file, String& type );
 bool getObjectType( const String& file_name, String& type );
 
 bool parseObjectType( const String& objectType,
-                      List< String >& parsedObjectType );
+                      Containers::List< String >& parsedObjectType );
 
 } // namespace TNL
diff --git a/src/TNL/Operators/Advection/CMakeLists.txt b/src/TNL/Operators/Advection/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5dff0bfc3dc52d76e01bfb2b8102946c27c451dd
--- /dev/null
+++ b/src/TNL/Operators/Advection/CMakeLists.txt
@@ -0,0 +1,6 @@
+SET( headers LaxFridrichs.h )
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Operators/Advection )
+
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Advection )
diff --git a/src/TNL/Operators/Advection/LaxFridrichs.h b/src/TNL/Operators/Advection/LaxFridrichs.h
new file mode 100644
index 0000000000000000000000000000000000000000..9dff03402a5bfef768e8ca608bd8dbbd10a38998
--- /dev/null
+++ b/src/TNL/Operators/Advection/LaxFridrichs.h
@@ -0,0 +1,317 @@
+#ifndef LaxFridrichs_H
+#define LaxFridrichs_H
+
+#include <TNL/Containers/Vector.h>
+#include <TNL/Meshes/Grid.h>
+#include <TNL/Functions/VectorField.h>
+#include <TNL/SharedPointer.h>
+
+namespace TNL {
+   namespace Operators {
+      namespace Advection {
+   
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType,
+          typename VelocityFunction = Functions::MeshFunction< Mesh > >
+class LaxFridrichs
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename VelocityFunction >
+class LaxFridrichs< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction >
+{
+   public:
+      
+      typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef SharedPointer< MeshType > MeshPointer;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      typedef VelocityFunction VelocityFunctionType;
+      typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer;
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 );
+      }
+      
+      LaxFridrichs()
+         : artificialViscosity( 1.0 ) {}
+      
+      LaxFridrichs( const VelocityFieldPointer& velocityField )
+         : artificialViscosity( 1.0 ), velocityField( velocityField ) {}
+      
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" );
+         return true;
+      }
+
+      static String getType();
+      
+      void setViscosity(const Real& artificalViscosity)
+      {
+         this->artificialViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityField( const VelocityFieldPointer& velocityField )
+      {
+         this->velocityField = velocityField;
+      }
+      
+      const VelocityFieldPointer& getVelocityField() const
+      {
+         return this->velocityField;
+      }
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
+
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+         const IndexType& center = entity.getIndex(); 
+         const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); 
+         typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter;
+         return ( 0.5 / this->tau ) * this->artificialViscosity * ( u[ west ]- 2.0 * u[ center ] + u[ east ] ) -
+                FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse * 0.5;
+      }
+      
+   protected:
+            
+      RealType tau;
+      
+      RealType artificialViscosity;
+      
+      VelocityFieldPointer velocityField;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename VelocityFunction >
+class LaxFridrichs< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction >
+{
+   public:
+      
+      typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef SharedPointer< MeshType > MeshPointer;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      typedef VelocityFunction VelocityFunctionType;
+      typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer;
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 );
+      }      
+      
+      LaxFridrichs()
+         : artificialViscosity( 1.0 ) {}
+
+      LaxFridrichs( const VelocityFieldPointer& velocityField )
+         : artificialViscosity( 1.0 ), velocityField( velocityField ) {}      
+      
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" );
+         return true;
+      }
+
+      static String getType();
+      
+      void setViscosity(const Real& artificalViscosity)
+      {
+         this->artificialViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityField( const VelocityFieldPointer& velocityField )
+      {
+         this->velocityField = velocityField;
+      }
+      
+      const VelocityFieldPointer& getVelocityField() const
+      {
+         return this->velocityField;
+      }
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
+
+         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  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >(); 
+         
+         typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter;
+         return ( 0.25 / this->tau ) * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ north ] + u[ south ] - 4.0 * u[ center ] ) -
+                0.5 * ( FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse +
+                        FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ], entity, time ) * ( u[ north ] - u[ south ] ) * hyInverse );         
+      }
+      
+   protected:
+            
+      RealType tau;
+      
+      RealType artificialViscosity;
+      
+      VelocityFieldPointer velocityField;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename VelocityFunction >
+class LaxFridrichs< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction >
+{
+   public:
+      
+      typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef SharedPointer< MeshType > MeshPointer;
+      static const int Dimensions = MeshType::getMeshDimension();
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Functions::MeshFunction< MeshType > MeshFunctionType;
+      typedef VelocityFunction VelocityFunctionType;
+      typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType;
+      typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer;
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 );
+      }      
+      
+      LaxFridrichs()
+         : artificialViscosity( 1.0 ) {}
+
+      LaxFridrichs( const VelocityFieldPointer& velocityField )
+         : artificialViscosity( 1.0 ), velocityField( velocityField ) {}
+            
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" );
+         return true;
+      }
+
+      static String getType();
+      
+      void setViscosity(const Real& artificalViscosity)
+      {
+         this->artificialViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityField( const VelocityFieldPointer& velocityField )
+      {
+         this->velocityField = velocityField;
+      }
+      
+      const VelocityFieldPointer& getVelocityField() const
+      {
+         return this->velocityField;
+      }
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
+
+         const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >(); 
+         const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >(); 
+         const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >(); 
+         const IndexType& center = entity.getIndex();
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >(); 
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >(); 
+         
+         typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter;
+         return ( 0.25 / this->tau ) * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ north ] + u[ south ] + u[ up ] + u[ down ] - 6.0 * u[ center ] ) -
+                0.5 * ( FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse +
+                        FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ], entity, time ) * ( u[ north ] - u[ south ] ) * hyInverse +
+                        FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 2 ], entity, time ) * ( u[ up ] - u[ down ] ) * hzInverse );         
+      }
+      
+   protected:
+            
+      RealType tau;
+      
+      RealType artificialViscosity;
+      
+      VelocityFieldPointer velocityField;
+};
+
+      }// namespace Advection
+   } // namepsace Operators
+} // namespace TNL
+
+#endif	/* LaxFridrichs_H */
diff --git a/src/TNL/Operators/Analytic/CMakeLists.txt b/src/TNL/Operators/Analytic/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8cc44ea6f704cdb0086ab9925e60e7c580e125ac
--- /dev/null
+++ b/src/TNL/Operators/Analytic/CMakeLists.txt
@@ -0,0 +1,11 @@
+SET( headers Sign.h
+             Heaviside.h
+             Identity.h
+             SmoothHeaviside.h
+             Shift.h
+             Rotation.h )
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Operators/Analytic )
+
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Analytic )
diff --git a/src/TNL/Operators/Analytic/Heaviside.h b/src/TNL/Operators/Analytic/Heaviside.h
new file mode 100644
index 0000000000000000000000000000000000000000..469cd7e1b849646840680303e75da344f4835aa4
--- /dev/null
+++ b/src/TNL/Operators/Analytic/Heaviside.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+                          Heaviside.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Functions/Domain.h>
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+   
+template< int Dimensions,
+          typename Real = double >
+class Heaviside : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions, 
+                                        RealType > PointType;
+      
+      Heaviside() : multiplicator( 1.0 ) {}
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "multiplicator", "Outer multiplicator of the Heaviside operator - -1.0 turns the function graph upside/down.", 1.0 );
+      }      
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->multiplicator = parameters.getParameter< double >( prefix + "multiplicator" );
+         return true;
+      };
+      
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {
+         const RealType aux = function( vertex, time );
+         if( aux > 0.0 )
+            return 1.0;
+         return 0.0;
+      }
+      
+      template< typename Function,
+                int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const Function& function,
+                                     const PointType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+            return this->operator()( function, vertex, time );
+         return 0.0;
+      }
+      
+   protected:
+      
+      RealType multiplicator;
+      
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Operators/Analytic/Identity.h b/src/TNL/Operators/Analytic/Identity.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0c21a57ea0fd49b35067c6614488bb8e7177931
--- /dev/null
+++ b/src/TNL/Operators/Analytic/Identity.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+                          Identity.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+   
+template< int Dimensions, typename Real >
+class Identity : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions, RealType > PointType;
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         return true;
+      };
+      
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {
+         return function( vertex, time );
+      }
+      
+      template< typename Function,
+                int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const Function& function,
+                                     const PointType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         return function.template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
diff --git a/src/TNL/Operators/Analytic/Rotation.h b/src/TNL/Operators/Analytic/Rotation.h
new file mode 100644
index 0000000000000000000000000000000000000000..894012ef788caa3542f0593d2834e594cdaeff34
--- /dev/null
+++ b/src/TNL/Operators/Analytic/Rotation.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+                          Rotation.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+
+// TODO: Implement RotationXY, RotationXZ and RotationYZ in all dimensions. 
+//       Where it does not make sense, the operator does nothing.   
+   
+template< typename Real,
+          int Dimensions >
+class RotationBase
+{
+   public:
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimenions, RealType > PointType;
+      
+      RotationBase() : center( 0.0 ) {};
+      
+      void setCenter( const PointType& center )
+      {
+         this->center = center;
+      }
+      
+      __cuda_callable__
+      const PointType& getCenter() const
+      {
+         return this->center;
+      }
+      
+   protected:
+      
+      PointType center;
+};
+   
+template< typename Function,
+          int Dimensions = Function::getDomainDimenions() >
+class Rotation;
+
+template< typename Function, 1 >
+class Rotation: public Functions::Domain< Function::getDomainDimenions(), 
+                                          Function::getDomainType() >
+{
+   public:
+      
+      typedef typename Function::RealType RealType;
+      typedef Containers::StaticVector< Function::getDomainDimenions(), 
+                                        RealType > PointType;
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" ){};
+      
+      
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {
+         return function( vertex, time );
+      }
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
diff --git a/src/TNL/Operators/Analytic/Shift.h b/src/TNL/Operators/Analytic/Shift.h
new file mode 100644
index 0000000000000000000000000000000000000000..d41464fad3b9f1297a3de4860168169337ad9336
--- /dev/null
+++ b/src/TNL/Operators/Analytic/Shift.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+                          Shift.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+#include <TNL/Containers/StaticVector.h>
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+   
+template< int Dimensions, typename Real >
+class Shift : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions, RealType > PointType;
+      
+      
+      Shift() : shift( 0.0 ) {};
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "shift-0", "x-coordinate of the shift vector.", 0.0 );
+         config.addEntry< double >( prefix + "shift-1", "y-coordinate of the shift vector.", 0.0 );
+         config.addEntry< double >( prefix + "shift-2", "z-coordinate of the shift vector.", 0.0 );
+      }      
+            
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         return shift.setup( parameters, prefix + "shift-" );
+      };
+      
+      
+      void setShift( const PointType& shift )
+      {
+         this->shift = shift;
+      }
+      
+      __cuda_callable__
+      const PointType& getShift() const
+      {
+         return this->shift;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {         
+         return function( vertex - this->shift, time );
+      }
+      
+      template< typename Function, 
+                int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const Function& function,
+                                     const PointType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+            return this->operator()( function, vertex - this->shift, time );
+         // TODO: implement the rest
+      }
+      
+      
+   protected:
+      
+      PointType shift;
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
diff --git a/src/TNL/Operators/Analytic/Sign.h b/src/TNL/Operators/Analytic/Sign.h
new file mode 100644
index 0000000000000000000000000000000000000000..eab3f12b410e40298a7b55b533bec452b6abc78a
--- /dev/null
+++ b/src/TNL/Operators/Analytic/Sign.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+                          Sign.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+   
+template< int Dimensions,
+          typename Real >
+class Sign : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+{
+   public:
+      
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions, RealType > PointType;
+      
+      Sign()
+         : positiveValue( 1.0 ),
+           negativeValue( -1.0 ),
+           zeroValue( 0.0 ) {}
+      
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         config.addEntry< double >( prefix + "positive-value", "Value returned for positive argument.", 1.0 );
+         config.addEntry< double >( prefix + "negative-value", "Value returned for negative argument.", -1.0 );
+         config.addEntry< double >( prefix + "zero-value", "Value returned for zero argument.", 0.0 );
+      }
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         this->positiveValue = parameters.getParameter< double >( prefix + "positive-value" );
+         this->negativeValue = parameters.getParameter< double >( prefix + "negative-value" );
+         this->zeroValue = parameters.getParameter< double >( prefix + "zero-value" );
+         return true;
+      };      
+      
+      void setPositiveValue( const RealType& value )
+      {
+         this->positiveValue = value;
+      }
+      
+      const RealType& getPositiveValue() const
+      {
+         return this->positiveValue;
+      }
+      
+      void setNegativeValue( const RealType& value )
+      {
+         this->negativeValue = value;
+      }
+      
+      const RealType& getNegativeValue() const
+      {
+         return this->negativeValue;
+      }
+      
+      void setZeroValue( const RealType& value )
+      {
+         this->zeroValue = value;
+      }
+      
+      const RealType& getZeroValue() const
+      {
+         return this->zeroValue;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {
+         const RealType aux = function( vertex, time );
+         if( aux > 0.0 )
+            return this->positiveValue;
+         else
+            if( aux < 0.0 )
+               return this->negativeValue;
+         return this->zeroValue;         
+      }
+      
+      template< typename Function,
+                int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const Function& function,
+                                     const PointType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+            return this->operator()( function, vertex, time );
+         return 0.0;
+      }
+      
+   protected:
+      
+      RealType positiveValue, negativeValue, zeroValue;
+      
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
diff --git a/src/TNL/Operators/Analytic/SmoothHeaviside.h b/src/TNL/Operators/Analytic/SmoothHeaviside.h
new file mode 100644
index 0000000000000000000000000000000000000000..060057bff7b6c9de1920239649baf48812dd55e6
--- /dev/null
+++ b/src/TNL/Operators/Analytic/SmoothHeaviside.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+                          SmoothHeaviside.h  -  description
+                             -------------------
+    begin                : Feb 6, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Functions/Domain.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Config/ParameterContainer.h>
+
+namespace TNL {
+namespace Operators {
+namespace Analytic {   
+   
+   
+template< typename Function >
+class SmoothHeaviside : public Functions::Domain< Function::getDomainDimenions(), 
+                                                  Function::getDomainTyep() >
+{
+   public:
+      
+      typedef typename Function::RealType RealType;
+      typedef Containers::StaticVector< Function::getDomainDimenions(), 
+                                        RealType > PointType;
+      
+      SmoothHeaviside()
+      : sharpness( 1.0 ){}
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" ){};
+      
+      
+      void setSharpness( const RealType& sharpness )
+      {
+         this->sharpness = sharpness;
+      }
+      
+      __cuda_callable__
+      const RealType getShaprness() const
+      {
+         return this->sharpness;
+      }
+      
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const PointType& vertex,
+                           const RealType& time = 0 ) const
+      {
+         const RealType aux = function( vertex, time );
+         return 1.0 / ( 1.0 + exp( -2.0 * sharpness * aux ) );
+      }
+      
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const Function& function,
+                                     const PointType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+            return this->operator()( function, vertex, time );
+         // TODO: implement the rest
+      }
+      
+   protected:
+
+      RealType sharpness;
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
diff --git a/src/TNL/Operators/CMakeLists.txt b/src/TNL/Operators/CMakeLists.txt
old mode 100755
new mode 100644
index dcdb7d3ddaae05cffedbe0d9468002b63ca41328..63385c2a49e16c771f1c7970180ddd97ac3be5f4
--- a/src/TNL/Operators/CMakeLists.txt
+++ b/src/TNL/Operators/CMakeLists.txt
@@ -1,9 +1,12 @@
+ADD_SUBDIRECTORY( Advection )
+ADD_SUBDIRECTORY( Analytic )
 ADD_SUBDIRECTORY( diffusion )
 ADD_SUBDIRECTORY( euler )
 ADD_SUBDIRECTORY( interpolants )
 ADD_SUBDIRECTORY( operator-Q )
 ADD_SUBDIRECTORY( operator-curvature )
 
+
 SET( headers DirichletBoundaryConditions.h
              ExactFunctionInverseOperator.h
              ExactIdentityOperator.h
@@ -23,6 +26,11 @@ if( BUILD_CUDA)
         ${tnl_operators_diffusion_CUDA__SOURCES}
         ${tnl_operators_gradient_CUDA__SOURCES}
         ${tnl_operators_euler_CUDA__SOURCES}
+#        ${tnl_operators_godunov_CUDA__SOURCES}
+        ${tnl_operators_godunov-eikonal_CUDA__SOURCES}
+#        ${tnl_operators_upwind_CUDA__SOURCES}
+#        ${tnl_operators_upwind-eikonal_CUDA__SOURCES}
+        ${common_SOURCES}
         ${common_SOURCES}
         PARENT_SCOPE )
 endif()
@@ -31,6 +39,10 @@ set( tnl_operators_SOURCES
      ${tnl_operators_diffusion_SOURCES}
      ${tnl_operators_gradient_SOURCES}
      ${tnl_operators_euler_SOURCES}
+#     ${tnl_operators_godunov_SOURCES}
+     ${tnl_operators_godunov-eikonal_SOURCES}
+#     ${tnl_operators_upwind_SOURCES}
+#     ${tnl_operators_upwind-eikonal_SOURCES}
      ${common_SOURCES}
      PARENT_SCOPE )
    
diff --git a/src/TNL/Operators/DirichletBoundaryConditions.h b/src/TNL/Operators/DirichletBoundaryConditions.h
index 0e50373b7fcecd45472fa5f4275a0f3b13e8eae6..759db071cf8af223abedc6899e1787f45ab76ee3 100644
--- a/src/TNL/Operators/DirichletBoundaryConditions.h
+++ b/src/TNL/Operators/DirichletBoundaryConditions.h
@@ -19,15 +19,15 @@ namespace TNL {
 namespace Operators {
 
 template< typename Mesh,
-          typename Function = Functions::Analytic::Constant< Mesh::getMeshDimensions(), typename Mesh::RealType >,
-          int MeshEntitiesDimensions = Mesh::getMeshDimensions(),
+          typename Function = Functions::Analytic::Constant< Mesh::getMeshDimension(), typename Mesh::RealType >,
+          int MeshEntitiesDimension = Mesh::getMeshDimension(),
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class DirichletBoundaryConditions
 : public Operator< Mesh,
                    Functions::MeshBoundaryDomain,
-                   MeshEntitiesDimensions,
-                   MeshEntitiesDimensions,
+                   MeshEntitiesDimension,
+                   MeshEntitiesDimension,
                    Real,
                    Index >
 {
@@ -41,9 +41,9 @@ class DirichletBoundaryConditions
       
       typedef SharedPointer< Mesh > MeshPointer;
       typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
 
-      static constexpr int getMeshDimensions() { return MeshType::meshDimensions; }
+      static constexpr int getMeshDimension() { return MeshType::getMeshDimension(); }
 
       static void configSetup( Config::ConfigDescription& config,
                                const String& prefix = "" )
@@ -80,7 +80,7 @@ class DirichletBoundaryConditions
                                  const EntityType& entity,
                                  const RealType& time = 0 ) const
       {
-         //static_assert( EntityType::getDimensions() == MeshEntitiesDimensions, "Wrong mesh entity dimensions." );
+         //static_assert( EntityType::getDimension() == MeshEntitiesDimension, "Wrong mesh entity dimension." );
          return Functions::FunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time );
       }
 
diff --git a/src/TNL/Operators/ExactFunctionInverseOperator.h b/src/TNL/Operators/ExactFunctionInverseOperator.h
index dca0666ab6889e1b4d016f53b8a89d747f8cdb47..7833d05445fd6c49f0971a5c57c0d7c4cdcea37c 100644
--- a/src/TNL/Operators/ExactFunctionInverseOperator.h
+++ b/src/TNL/Operators/ExactFunctionInverseOperator.h
@@ -18,17 +18,17 @@
 namespace TNL {
 namespace Operators {
 
-template< int Dimensions,
-          typename InnerOperator= ExactIdentityOperator< Dimensions > >
+template< int Dimension,
+          typename InnerOperator= ExactIdentityOperator< Dimension > >
 class ExactFunctionInverseOperator
-   : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+   : public Functions::Domain< Dimension, Functions::SpaceDomain >
 {
    public:
  
       static String getType()
       {
          return String( "ExactFunctionInverseOperator< " ) +
-                String( Dimensions) + " >";
+                String( Dimension) + " >";
       }
  
       InnerOperator& getInnerOperator()
@@ -45,7 +45,7 @@ class ExactFunctionInverseOperator
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -59,7 +59,7 @@ class ExactFunctionInverseOperator
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
diff --git a/src/TNL/Operators/ExactIdentityOperator.h b/src/TNL/Operators/ExactIdentityOperator.h
index ee7ea78304f1996aef915ba760410c539d20944e..7c39938df87fb6a1863d82ea13d54e2e4e482c1a 100644
--- a/src/TNL/Operators/ExactIdentityOperator.h
+++ b/src/TNL/Operators/ExactIdentityOperator.h
@@ -17,23 +17,23 @@
 namespace TNL {
 namespace Operators {
 
-template< int Dimensions >
+template< int Dimension >
 class ExactIdentityOperator
-   : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+   : public Functions::Domain< Dimension, Functions::SpaceDomain >
 {
    public:
  
       static String getType()
       {
          return String( "ExactIdentityOperator< " ) +
-                String( Dimensions) + " >";
+                String( Dimension) + " >";
       }
  
       template< typename Function >
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          return function( v, time );
@@ -46,7 +46,7 @@ class ExactIdentityOperator
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
diff --git a/src/TNL/Operators/ExactOperatorComposition.h b/src/TNL/Operators/ExactOperatorComposition.h
index b2d487832563ee501fed1a8e9bf214c552230603..e1a3ca6230402269aea0113a9666d043be0f2d43 100644
--- a/src/TNL/Operators/ExactOperatorComposition.h
+++ b/src/TNL/Operators/ExactOperatorComposition.h
@@ -22,7 +22,7 @@ class ExactOperatorComposition
       template< typename Function >
       __cuda_callable__ inline
       typename Function::RealType operator()( const Function& function,
-                                              const typename Function::VertexType& v,
+                                              const typename Function::PointType& v,
                                               const typename Function::RealType& time = 0.0 ) const
       {
          return OuterOperator( innerOperator( function, v, time), v, time );
diff --git a/src/TNL/Operators/FiniteDifferences.h b/src/TNL/Operators/FiniteDifferences.h
index 36b8a3948bc9c3b1534258d741eb03d193dcf940..24ca76f82ee9009d6dc7e98f62b6a96340130f59 100644
--- a/src/TNL/Operators/FiniteDifferences.h
+++ b/src/TNL/Operators/FiniteDifferences.h
@@ -33,18 +33,6 @@ class FiniteDifferences< Meshes::Grid< 1, Real, Device, Index > >
    typedef typename GridType::Cell CellType;
 
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const GridFunction& inFunction,
-                                  GridFunction& outFunction );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -55,20 +43,7 @@ class FiniteDifferences< Meshes::Grid< 1, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const GridFunction& inFunction,
                                   GridFunction& outFunction );
-#endif
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const CellType& cell,
-                                  const GridFunction& function );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -79,8 +54,6 @@ class FiniteDifferences< Meshes::Grid< 1, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const CellType& cell,
                                   const GridFunction& function );
-#endif
-
 };
 
 template< typename Real, typename Device, typename Index >
@@ -96,18 +69,6 @@ class FiniteDifferences< Meshes::Grid< 2, Real, Device, Index > >
    typedef typename GridType::Cell CellType;
 
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const GridFunction& inFunction,
-                                  GridFunction& outFunction );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -118,20 +79,7 @@ class FiniteDifferences< Meshes::Grid< 2, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const GridFunction& inFunction,
                                   GridFunction& outFunction );
-#endif
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const CellType& cell,
-                                  const GridFunction& function );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -142,8 +90,6 @@ class FiniteDifferences< Meshes::Grid< 2, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const CellType& cell,
                                   const GridFunction& function );
-#endif
-
 };
 
 template< typename Real, typename Device, typename Index >
@@ -158,18 +104,6 @@ class FiniteDifferences< Meshes::Grid< 3, Real, Device, Index > >
    //typedef typename GridType::CoordinatesType CoordinatesType;
    typedef typename GridType::Cell CellType;
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const GridFunction& inFunction,
-                                  GridFunction& outFunction );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -180,20 +114,7 @@ class FiniteDifferences< Meshes::Grid< 3, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const GridFunction& inFunction,
                                   GridFunction& outFunction );
-#endif
 
-#ifdef HAVE_NOT_CXX11
-   template< typename GridFunction,
-             int XDifferenceOrder,
-             int YDifferenceOrder,
-             int ZDifferenceOrder,
-             int XDifferenceDirection,
-             int YDifferenceDirection,
-             int ZDifferenceDirection >
-   static RealType getDifference( const GridType& grid,
-                                  const CellType& cell,
-                                  const GridFunction& function );
-#else
    template< typename GridFunction,
              int XDifferenceOrder,
              int YDifferenceOrder,
@@ -204,11 +125,9 @@ class FiniteDifferences< Meshes::Grid< 3, Real, Device, Index > >
    static RealType getDifference( const GridType& grid,
                                   const CellType& cell,
                                   const GridFunction& function );
-#endif
-
 };
 
 } // namespace Operators
 } // namespace TNL
 
-#include <TNL/Operators/FiniteDifferences_impl.h>
\ No newline at end of file
+#include <TNL/Operators/FiniteDifferences_impl.h>
diff --git a/src/TNL/Operators/FiniteDifferences_impl.h b/src/TNL/Operators/FiniteDifferences_impl.h
index 51cc742999d7fc40bdb2e5fd75363ecc3ec6a335..3d5b5bace6fa1cd9d9566581fbe113ebba06437d 100644
--- a/src/TNL/Operators/FiniteDifferences_impl.h
+++ b/src/TNL/Operators/FiniteDifferences_impl.h
@@ -69,22 +69,22 @@ Real FiniteDifferences< Meshes::Grid< 1, Real, Device, Index > >::getDifference(
    if( YDifferenceOrder > 0 || ZDifferenceOrder > 0 )
       return 0.0;
    const RealType hx = grid.getSpaceSteps().x();
-   auto neighbourEntities = cell.getNeighbourEntities();
+   auto neighborEntities = cell.getNeighborEntities();
    IndexType cellIndex = grid.getEntityIndex( cell );
    if( XDifferenceOrder == 1 )
    {
       if( XDifferenceDirection == 0 )
-         return ( function[ neighbourEntities.template getEntityIndex< 1 >() ] -
-                  function[ neighbourEntities.template getEntityIndex< -1 >() ] ) / ( 2.0 * hx );
+         return ( function[ neighborEntities.template getEntityIndex< 1 >() ] -
+                  function[ neighborEntities.template getEntityIndex< -1 >() ] ) / ( 2.0 * hx );
       else
-         return ( function[ neighbourEntities.template getEntityIndex< XDifferenceDirection >() ] -
+         return ( function[ neighborEntities.template getEntityIndex< XDifferenceDirection >() ] -
                   function[ cellIndex ] ) / ( XDifferenceDirection * hx );
    }
    if( XDifferenceOrder == 2 )
    {
-      return ( function[ neighbourEntities.template getEntityIndex< 1 >() ] -
+      return ( function[ neighborEntities.template getEntityIndex< 1 >() ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< -1 >() ] ) / (  hx * hx );
+               function[ neighborEntities.template getEntityIndex< -1 >() ] ) / (  hx * hx );
    }
 }
 
@@ -121,33 +121,33 @@ Real FiniteDifferences< Meshes::Grid< 2, Real, Device, Index > >::getDifference(
 {
    if( ZDifferenceOrder > 0 )
       return 0.0;
-   auto neighbourEntities = cell.getNeighbourEntities();
+   auto neighborEntities = cell.getNeighborEntities();
    IndexType cellIndex = grid.getEntityIndex( cell );
    if( XDifferenceOrder == 1 )
    {
       const RealType hx = grid.getSpaceSteps().x();
-      return ( function[ neighbourEntities.template getEntityIndex< XDifferenceDirection, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< XDifferenceDirection, 0 >( cellIndex ) ] -
                function[ cellIndex ] ) / ( XDifferenceDirection * hx );
    }
    if( XDifferenceOrder == 2 )
    {
       const RealType hx = grid.getSpaceSteps().x();
-      return ( function[ neighbourEntities.template getEntityIndex< 1, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 1, 0 >( cellIndex ) ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< -1, 0 >( cellIndex ) ] ) / (  hx * hx );
+               function[ neighborEntities.template getEntityIndex< -1, 0 >( cellIndex ) ] ) / (  hx * hx );
    }
    if( YDifferenceOrder == 1 )
    {
       const RealType hy = grid.getSpaceSteps().y();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, YDifferenceDirection >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, YDifferenceDirection >( cellIndex ) ] -
                function[ cellIndex ] ) / ( YDifferenceDirection * hy );
    }
    if( YDifferenceOrder == 2 )
    {
       const RealType hy = grid.getSpaceSteps().y();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, 1 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, 1 >( cellIndex ) ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< 0, -1 >( cellIndex ) ] ) / (  hy * hy );
+               function[ neighborEntities.template getEntityIndex< 0, -1 >( cellIndex ) ] ) / (  hy * hy );
    }
 
 
@@ -184,47 +184,47 @@ Real FiniteDifferences< Meshes::Grid< 3, Real, Device, Index > >::getDifference(
                                                                                const CellType& cell,
                                                                                const GridFunction& function )
 {
-   auto neighbourEntities = cell.getNeighbourEntities();
+   auto neighborEntities = cell.getNeighborEntities();
    IndexType cellIndex = grid.getEntityIndex( cell );
 
    if( XDifferenceOrder == 1 )
    {
       const RealType hx = grid.getSpaceSteps().x();
-      return ( function[ neighbourEntities.template getEntityIndex< XDifferenceDirection, 0, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< XDifferenceDirection, 0, 0 >( cellIndex ) ] -
                function[ cellIndex ] ) / ( XDifferenceDirection * hx );
    }
    if( XDifferenceOrder == 2 )
    {
       const RealType hx = grid.getSpaceSteps().x();
-      return ( function[ neighbourEntities.template getEntityIndex< 1, 0, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 1, 0, 0 >( cellIndex ) ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< -1, 0, 0 >( cellIndex ) ] ) / (  hx * hx );
+               function[ neighborEntities.template getEntityIndex< -1, 0, 0 >( cellIndex ) ] ) / (  hx * hx );
    }
    if( YDifferenceOrder == 1 )
    {
       const RealType hy = grid.getSpaceSteps().y();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, YDifferenceDirection, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, YDifferenceDirection, 0 >( cellIndex ) ] -
                function[ cellIndex ] ) / ( YDifferenceDirection * hy );
    }
    if( YDifferenceOrder == 2 )
    {
       const RealType hy = grid.getSpaceSteps().y();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, 1, 0 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, 1, 0 >( cellIndex ) ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< 0, -1, 0 >( cellIndex ) ] ) / (  hy * hy );
+               function[ neighborEntities.template getEntityIndex< 0, -1, 0 >( cellIndex ) ] ) / (  hy * hy );
    }
    if( ZDifferenceOrder == 1 )
    {
       const RealType hz = grid.getSpaceSteps().z();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, 0, ZDifferenceDirection >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, 0, ZDifferenceDirection >( cellIndex ) ] -
                function[ cellIndex ] ) / ( ZDifferenceDirection * hz );
    }
    if( ZDifferenceOrder == 2 )
    {
       const RealType hz = grid.getSpaceSteps().z();
-      return ( function[ neighbourEntities.template getEntityIndex< 0, 0, 1 >( cellIndex ) ] -
+      return ( function[ neighborEntities.template getEntityIndex< 0, 0, 1 >( cellIndex ) ] -
                2.0 * function[ cellIndex ] +
-               function[ neighbourEntities.template getEntityIndex< 0, 0, -1 >( cellIndex ) ] ) / (  hz * hz );
+               function[ neighborEntities.template getEntityIndex< 0, 0, -1 >( cellIndex ) ] ) / (  hz * hz );
    }
 
 
diff --git a/src/TNL/Operators/FunctionInverseOperator.h b/src/TNL/Operators/FunctionInverseOperator.h
index 1a849f9ed2de751d16000dfc6d1e41b357755f9c..f202d870cf79e1888fc3a9daf7701b94bfb928c8 100644
--- a/src/TNL/Operators/FunctionInverseOperator.h
+++ b/src/TNL/Operators/FunctionInverseOperator.h
@@ -21,8 +21,8 @@ template< typename OperatorT >
 class FunctionInverseOperator
 : public Operator< typename OperatorT::MeshType,
                       OperatorT::getDomainType(),
-                      OperatorT::getPreimageEntitiesDimensions(),
-                      OperatorT::getImageEntitiesDimensions(),
+                      OperatorT::getPreimageEntitiesDimension(),
+                      OperatorT::getImageEntitiesDimension(),
                       typename OperatorT::RealType,
                       typename OperatorT::IndexType >
 {
diff --git a/src/TNL/Operators/IdentityOperator.h b/src/TNL/Operators/IdentityOperator.h
index afe0e3d2a314fb02dde40990a188c461f207b7c3..f48fbc8347887b8d923ff36622acde08d47d6d98 100644
--- a/src/TNL/Operators/IdentityOperator.h
+++ b/src/TNL/Operators/IdentityOperator.h
@@ -17,7 +17,7 @@ namespace Operators {
 
 template< typename MeshFunction >
 class IdentityOperator
-   : public Domain< MeshFunction::getDimensions(), MeshFunction::getDomainType() >
+   : public Domain< MeshFunction::getMeshDimension(), MeshFunction::getDomainType() >
 {
    public:
  
@@ -35,7 +35,7 @@ class IdentityOperator
          const MeshEntity& meshEntity,
          const RealType& time = 0 ) const
       {
-         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+         static_assert( MeshFunction::getMeshDimension() == InnerOperator::getDimension(),
             "Mesh function and operator have both different number of dimensions." );
          return this->meshFunction( meshEntity, time );
       }
diff --git a/src/TNL/Operators/NeumannBoundaryConditions.h b/src/TNL/Operators/NeumannBoundaryConditions.h
index 1461135eebaa135043e1f60452a178f2633b4737..15cfbe85c68e8e986e8d50dc8f1c83c24c36fb7b 100644
--- a/src/TNL/Operators/NeumannBoundaryConditions.h
+++ b/src/TNL/Operators/NeumannBoundaryConditions.h
@@ -19,7 +19,7 @@ namespace Operators {
 template< typename Mesh,
           typename Function,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class NeumannBoundaryConditions
 {
 
@@ -49,10 +49,22 @@ class NeumannBoundaryConditionsBase
          return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix );
       }
 
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" )
+      {
+         Function::configSetup( config, prefix );
+      };
+
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+          return this->function.setup( parameters, prefix );
+      };
+
       void setFunction( const FunctionType& function )
       {
          this->function = function;
-      }
+      };
       
       FunctionType& getFunction()
       {
@@ -96,7 +108,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
 
    typedef Function FunctionType;
    typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
-   typedef Containers::StaticVector< 1, RealType > VertexType;
+   typedef Containers::StaticVector< 1, RealType > PointType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
    typedef NeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
    typedef NeumannBoundaryConditionsBase< Function > BaseType;
@@ -109,13 +121,13 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
                               const RealType& time = 0 ) const
    {
       const MeshType& mesh = entity.getMesh();
-      const auto& neighbourEntities = entity.getNeighbourEntities();
+      const auto& neighborEntities = entity.getNeighborEntities();
       const IndexType& index = entity.getIndex();
       if( entity.getCoordinates().x() == 0 )
-         return u[ neighbourEntities.template getEntityIndex< 1 >() ] - entity.getMesh().getSpaceSteps().x() * 
+         return u[ neighborEntities.template getEntityIndex< 1 >() ] + entity.getMesh().getSpaceSteps().x() * 
             Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
       else
-         return u[ neighbourEntities.template getEntityIndex< -1 >() ] + entity.getMesh().getSpaceSteps().x() * 
+         return u[ neighborEntities.template getEntityIndex< -1 >() ] + entity.getMesh().getSpaceSteps().x() * 
             Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );   
 
    }
@@ -142,19 +154,19 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
                                      Matrix& matrix,
                                      Vector& b ) const
       {
-         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const auto& neighborEntities = entity.getNeighborEntities();
          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() * 
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() * 
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          else
          {
-            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1 >(), -1.0 );
+            matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 );
             matrixRow.setElement( 1, index, 1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -189,7 +201,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
 
       typedef Function FunctionType;
       typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
-      typedef Containers::StaticVector< 2, RealType > VertexType;
+      typedef Containers::StaticVector< 2, RealType > PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef NeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
       typedef NeumannBoundaryConditionsBase< Function > BaseType;
@@ -203,27 +215,27 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
                                  const RealType& time = 0 ) const
       {
          const MeshType& mesh = entity.getMesh();
-         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const auto& neighborEntities = entity.getNeighborEntities();
          const IndexType& index = entity.getIndex();
          if( entity.getCoordinates().x() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+            return u[ neighborEntities.template getEntityIndex< 1, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< 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() *
+            return u[ neighborEntities.template getEntityIndex< -1, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().y() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - entity.getMesh().getSpaceSteps().y() *
+            return u[ neighborEntities.template getEntityIndex< 0, 1 >() ] + entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          // The following line is commented to avoid compiler warning
          //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + entity.getMesh().getSpaceSteps().y() *
+            return u[ neighborEntities.template getEntityIndex< 0, -1 >() ] + entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }         
       }
@@ -249,19 +261,19 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
                               Matrix& matrix,
                               Vector& b ) const
       {
-         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const auto& neighborEntities = entity.getNeighborEntities();
          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() *
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< 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( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 );
             matrixRow.setElement( 1, index,                                                 1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -269,13 +281,13 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
          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() *
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< 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( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 );
             matrixRow.setElement( 1, index,                                                 1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -309,7 +321,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
 
       typedef Function FunctionType;
       typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
-      typedef Containers::StaticVector< 3, RealType > VertexType;
+      typedef Containers::StaticVector< 3, RealType > PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef NeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
       typedef NeumannBoundaryConditionsBase< Function > BaseType;   
@@ -322,37 +334,37 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
                                  const RealType& time = 0 ) const
       {
          const MeshType& mesh = entity.getMesh();
-         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const auto& neighborEntities = entity.getNeighborEntities();
          const IndexType& index = entity.getIndex();
          if( entity.getCoordinates().x() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+            return u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< 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() *
+            return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().y() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - entity.getMesh().getSpaceSteps().y() *
+            return u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] + entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< 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() *
+            return u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ] + entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().z() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - entity.getMesh().getSpaceSteps().z() *
+            return u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] + entity.getMesh().getSpaceSteps().z() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          // The following line is commented to avoid compiler warning
          //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] + entity.getMesh().getSpaceSteps().z() *
+            return u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ] + entity.getMesh().getSpaceSteps().z() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }   
       }
@@ -379,19 +391,19 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
                                      Matrix& matrix,
                                      Vector& b ) const
       {
-         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const auto& neighborEntities = entity.getNeighborEntities();
          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() *
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< 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( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 );
             matrixRow.setElement( 1, index,                                                    1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -399,13 +411,13 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          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() * 
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().y() * 
                Functions::FunctionAdapter< 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( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 );
             matrixRow.setElement( 1, index,                                                    1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -413,13 +425,13 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          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() *
+            matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().z() *
                Functions::FunctionAdapter< 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( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 );
             matrixRow.setElement( 1, index,                                                    1.0 );
             b[ index ] = entity.getMesh().getSpaceSteps().z() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
@@ -440,4 +452,3 @@ std::ostream& operator << ( std::ostream& str, const NeumannBoundaryConditions<
 } // namespace Operators
 } // namespace TNL
 
-
diff --git a/src/TNL/Operators/Operator.h b/src/TNL/Operators/Operator.h
index f0cf536e1eacb460ac3144719408a769d7d19989..1a78fd5970a73650781f01fd593f40563797a432 100644
--- a/src/TNL/Operators/Operator.h
+++ b/src/TNL/Operators/Operator.h
@@ -17,25 +17,25 @@ namespace Operators {
 
 template< typename Mesh,
           Functions::DomainType DomainType = Functions::MeshInteriorDomain,
-          int PreimageEntitiesDimensions = Mesh::getMeshDimensions(),
-          int ImageEntitiesDimensions = Mesh::getMeshDimensions(),
+          int PreimageEntitiesDimension = Mesh::getMeshDimension(),
+          int ImageEntitiesDimension = Mesh::getMeshDimension(),
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class Operator : public Functions::Domain< Mesh::getMeshDimensions(), DomainType >
+          typename Index = typename Mesh::GlobalIndexType >
+class Operator : public Functions::Domain< Mesh::getMeshDimension(), DomainType >
 {
    public:
  
       typedef Mesh MeshType;
       typedef typename MeshType::RealType MeshRealType;
       typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType MeshIndexType;
+      typedef typename MeshType::GlobalIndexType MeshIndexType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef void ExactOperatorType;
  
-      constexpr static int getMeshDimensions() { return MeshType::getMeshDimensions(); }
-      constexpr static int getPreimageEntitiesDimensions() { return PreimageEntitiesDimensions; }
-      constexpr static int getImageEntitiesDimensions() { return ImageEntitiesDimensions; }
+      constexpr static int getMeshDimension() { return MeshType::getMeshDimension(); }
+      constexpr static int getPreimageEntitiesDimension() { return PreimageEntitiesDimension; }
+      constexpr static int getImageEntitiesDimension() { return ImageEntitiesDimension; }
  
       bool refresh( const RealType& time = 0.0 ) { return true; }
  
diff --git a/src/TNL/Operators/OperatorComposition.h b/src/TNL/Operators/OperatorComposition.h
index c935a3741607e025808c7664f07fb1077284602a..e4730c2429c9f98b6f331bd7564fc78c226708d8 100644
--- a/src/TNL/Operators/OperatorComposition.h
+++ b/src/TNL/Operators/OperatorComposition.h
@@ -32,8 +32,8 @@ template< typename OuterOperator,
 class OperatorComposition
    : public Operator< typename InnerOperator::MeshType,
                          InnerOperator::getDomainType(),
-                         InnerOperator::getPreimageEntitiesDimensions(),
-                         OuterOperator::getImageEntitiesDimensions(),
+                         InnerOperator::getPreimageEntitiesDimension(),
+                         OuterOperator::getImageEntitiesDimension(),
                          typename InnerOperator::RealType,
                          typename OuterOperator::IndexType >
 {
@@ -42,8 +42,8 @@ class OperatorComposition
    public:
  
       typedef typename InnerOperator::MeshType MeshType;
-      typedef Functions::MeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimensions() > PreimageFunctionType;
-      typedef Functions::MeshFunction< MeshType, InnerOperator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef Functions::MeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimension() > PreimageFunctionType;
+      typedef Functions::MeshFunction< MeshType, InnerOperator::getImageEntitiesDimension() > ImageFunctionType;
       typedef Functions::OperatorFunction< InnerOperator, PreimageFunctionType, InnerBoundaryConditions > InnerOperatorFunction;
       typedef Functions::OperatorFunction< InnerOperator, ImageFunctionType > OuterOperatorFunction;
       typedef typename InnerOperator::RealType RealType;
@@ -52,8 +52,8 @@ class OperatorComposition
                                            typename InnerOperator::ExactOperatorType > ExactOperatorType;
       typedef SharedPointer< MeshType > MeshPointer;
       
-      static constexpr int getPreimageEntitiesDimensions() { return InnerOperator::getImageEntitiesDimensions(); };
-      static constexpr int getImageEntitiesDimensions() { return OuterOperator::getImageEntitiesDimensions(); };
+      static constexpr int getPreimageEntitiesDimension() { return InnerOperator::getImageEntitiesDimension(); };
+      static constexpr int getImageEntitiesDimension() { return OuterOperator::getImageEntitiesDimension(); };
  
       OperatorComposition( OuterOperator& outerOperator,
                               InnerOperator& innerOperator,
@@ -102,7 +102,7 @@ class OperatorComposition
          const MeshEntity& meshEntity,
          const RealType& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+         static_assert( MeshFunction::getMeshDimension() == InnerOperator::getDimension(),
             "Mesh function and operator have both different number of dimensions." );
          //InnerOperatorFunction innerOperatorFunction( innerOperator, function );
          return outerOperator( innerOperatorFunction, meshEntity, time );
@@ -118,15 +118,15 @@ class OperatorComposition
 template< typename OuterOperator,
           typename InnerOperator >
 class OperatorComposition< OuterOperator, InnerOperator, void >
-   : public Functions::Domain< InnerOperator::getDimensions(), InnerOperator::getDomainType() >
+   : public Functions::Domain< InnerOperator::getDimension(), InnerOperator::getDomainType() >
 {
       static_assert( std::is_same< typename OuterOperator::MeshType, typename InnerOperator::MeshType >::value,
          "Both operators have different mesh types." );
    public:
  
       typedef typename InnerOperator::MeshType MeshType;
-      typedef Functions::MeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimensions() > PreimageFunctionType;
-      typedef Functions::MeshFunction< MeshType, InnerOperator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef Functions::MeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimension() > PreimageFunctionType;
+      typedef Functions::MeshFunction< MeshType, InnerOperator::getImageEntitiesDimension() > ImageFunctionType;
       typedef Functions::OperatorFunction< InnerOperator, PreimageFunctionType, void > InnerOperatorFunction;
       typedef Functions::OperatorFunction< InnerOperator, ImageFunctionType > OuterOperatorFunction;
       typedef typename InnerOperator::RealType RealType;
@@ -157,7 +157,7 @@ class OperatorComposition< OuterOperator, InnerOperator, void >
       bool refresh( const RealType& time = 0.0 )
       {
          return this->innerOperatorFunction.refresh( time );
-         /*MeshFunction< MeshType, MeshType::getMeshDimensions() - 1 > f( this->innerOperatorFunction.getMesh() );
+         /*MeshFunction< MeshType, MeshType::getMeshDimension() - 1 > f( this->innerOperatorFunction.getMesh() );
          f = this->innerOperatorFunction;
          this->innerOperatorFunction.getPreimageFunction().write( "preimageFunction", "gnuplot" );
          f.write( "innerFunction", "gnuplot" );
@@ -178,7 +178,7 @@ class OperatorComposition< OuterOperator, InnerOperator, void >
          const MeshEntity& meshEntity,
          const RealType& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+         static_assert( MeshFunction::getMeshDimension() == InnerOperator::getDimension(),
             "Mesh function and operator have both different number of dimensions." );
          //InnerOperatorFunction innerOperatorFunction( innerOperator, function );
          return outerOperator( innerOperatorFunction, meshEntity, time );
diff --git a/src/TNL/Operators/diffusion/CMakeLists.txt b/src/TNL/Operators/diffusion/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Operators/diffusion/ExactLinearDiffusion.h b/src/TNL/Operators/diffusion/ExactLinearDiffusion.h
index 46a88172fdb74673e291fe14394ea0367ac2fb25..790fa0777996839904b2c8270720dde20afc8946 100644
--- a/src/TNL/Operators/diffusion/ExactLinearDiffusion.h
+++ b/src/TNL/Operators/diffusion/ExactLinearDiffusion.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Functions/Domain.h>
@@ -15,7 +21,7 @@
 namespace TNL {
 namespace Operators {   
 
-template< int Dimensions >
+template< int Dimension >
 class ExactLinearDiffusion
 {};
 
@@ -24,14 +30,14 @@ class ExactLinearDiffusion< 1 > : public Functions::Domain< 1, Functions::SpaceD
 {
    public:
 
-      static const int Dimensions = 1;
+      static const int Dimension = 1;
  
       static String getType();
  
       template< typename Function >
       __cuda_callable__ inline
       typename Function::RealType operator()( const Function& function,
-                                              const typename Function::VertexType& v,
+                                              const typename Function::PointType& v,
                                               const typename Function::RealType& time = 0.0 ) const;
 };
 
@@ -40,14 +46,14 @@ class ExactLinearDiffusion< 2 > : public Functions::Domain< 2, Functions::SpaceD
 {
    public:
  
-      static const int Dimensions = 2;
+      static const int Dimension = 2;
  
       static String getType();
 
       template< typename Function >
       __cuda_callable__ inline
       typename Function::RealType operator()( const Function& function,
-                                              const typename Function::VertexType& v,
+                                              const typename Function::PointType& v,
                                               const typename Function::RealType& time = 0.0 ) const;
 };
 
@@ -56,14 +62,14 @@ class ExactLinearDiffusion< 3 > : public Functions::Domain< 3 >
 {
    public:
  
-      static const int Dimensions = 3;
+      static const int Dimension = 3;
  
       static String getType();
 
       template< typename Function >
       __cuda_callable__ inline
       typename Function::RealType operator()( const Function& function,
-                                              const typename Function::VertexType& v,
+                                              const typename Function::PointType& v,
                                               const typename Function::RealType& time = 0.0 ) const;
 };
 
diff --git a/src/TNL/Operators/diffusion/ExactLinearDiffusion_impl.h b/src/TNL/Operators/diffusion/ExactLinearDiffusion_impl.h
index 3e85c193b2071372f79c9f7ed283d872a41a0b7c..0aabb1027e38d3390ca009813e7ac1bf54cb006d 100644
--- a/src/TNL/Operators/diffusion/ExactLinearDiffusion_impl.h
+++ b/src/TNL/Operators/diffusion/ExactLinearDiffusion_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
@@ -25,7 +31,7 @@ __cuda_callable__ inline
 typename Function::RealType
 ExactLinearDiffusion< 1 >::
 operator()( const Function& function,
-            const typename Function::VertexType& v,
+            const typename Function::PointType& v,
             const typename Function::RealType& time ) const
 {
    return function.template getPartialDerivative< 2, 0, 0 >( v, time );
@@ -43,7 +49,7 @@ __cuda_callable__ inline
 typename Function::RealType
 ExactLinearDiffusion< 2 >::
 operator()( const Function& function,
-            const typename Function::VertexType& v,
+            const typename Function::PointType& v,
           const typename Function::RealType& time ) const
 {
    return function.template getPartialDerivative< 2, 0, 0 >( v, time ) +
@@ -62,7 +68,7 @@ __cuda_callable__ inline
 typename Function::RealType
 ExactLinearDiffusion< 3 >::
 operator()( const Function& function,
-            const typename Function::VertexType& v,
+            const typename Function::PointType& v,
             const typename Function::RealType& time ) const
 {
    return function.template getPartialDerivative< 2, 0, 0 >( v, time ) +
diff --git a/src/TNL/Operators/diffusion/ExactMeanCurvature.h b/src/TNL/Operators/diffusion/ExactMeanCurvature.h
index 04ac9df5d0642fdb9a6681b576099f7d8e6dd439..fbc2260efad49c99337d7af994bc3c61ef89c90e 100644
--- a/src/TNL/Operators/diffusion/ExactMeanCurvature.h
+++ b/src/TNL/Operators/diffusion/ExactMeanCurvature.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Operators/diffusion/ExactNonlinearDiffusion.h>
@@ -17,21 +23,21 @@
 namespace TNL {
 namespace Operators {   
 
-template< int Dimensions,
-          typename InnerOperator = ExactIdentityOperator< Dimensions > >
+template< int Dimension,
+          typename InnerOperator = ExactIdentityOperator< Dimension > >
 class ExactMeanCurvature
-: public Functions::Domain< Dimensions, Functions::SpaceDomain >
+: public Functions::Domain< Dimension, Functions::SpaceDomain >
 {
    public:
  
-      typedef ExactGradientNorm< Dimensions > ExactGradientNormType;
-      typedef ExactFunctionInverseOperator< Dimensions, ExactGradientNormType > FunctionInverse;
-      typedef ExactNonlinearDiffusion< Dimensions, FunctionInverse > NonlinearDiffusion;
+      typedef ExactGradientNorm< Dimension > ExactGradientNormType;
+      typedef ExactFunctionInverseOperator< Dimension, ExactGradientNormType > FunctionInverse;
+      typedef ExactNonlinearDiffusion< Dimension, FunctionInverse > NonlinearDiffusion;
  
       static String getType()
       {
          return String( "ExactMeanCurvature< " ) +
-                String( Dimensions) + ", " +
+                String( Dimension) + ", " +
                 InnerOperator::getType() + " >";
       }
  
@@ -45,7 +51,7 @@ class ExactMeanCurvature
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          return this->nonlinearDiffusion( function, v, time );
@@ -58,7 +64,7 @@ class ExactMeanCurvature
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
diff --git a/src/TNL/Operators/diffusion/ExactNonlinearDiffusion.h b/src/TNL/Operators/diffusion/ExactNonlinearDiffusion.h
index d1fc5e574ce2fbcd7f5e856d66c7bbc0a11b9c9f..25381e2bb48bcdbdbde8f419c1cac856f621d7fd 100644
--- a/src/TNL/Operators/diffusion/ExactNonlinearDiffusion.h
+++ b/src/TNL/Operators/diffusion/ExactNonlinearDiffusion.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Functions/Domain.h>
@@ -17,9 +23,9 @@
 namespace TNL {
 namespace Operators {   
 
-template<  int Dimensions,
+template<  int Dimension,
            typename Nonlinearity,
-           typename InnerOperator = ExactIdentityOperator< Dimensions > >
+           typename InnerOperator = ExactIdentityOperator< Dimension > >
 class ExactNonlinearDiffusion
 {};
 
@@ -60,7 +66,7 @@ class ExactNonlinearDiffusion< 1, Nonlinearity, InnerOperator >
       __cuda_callable__
       typename Function::RealType
       operator()( const Function& function,
-                  const typename Function::VertexType& v,
+                  const typename Function::PointType& v,
                   const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -114,7 +120,7 @@ class ExactNonlinearDiffusion< 2, Nonlinearity, InnerOperator >
       __cuda_callable__
       typename Function::RealType
       operator()( const Function& function,
-                  const typename Function::VertexType& v,
+                  const typename Function::PointType& v,
                   const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -173,7 +179,7 @@ class ExactNonlinearDiffusion< 3, Nonlinearity, InnerOperator >
       __cuda_callable__
       typename Function::RealType
       operator()( const Function& function,
-                  const typename Function::VertexType& v,
+                  const typename Function::PointType& v,
                   const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
diff --git a/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator.h b/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator.h
index 6daa0a2de9e8c33622c9525af9c13ffc52d38b54..efb17555547b53da1b850b789b6956674c1abbdf 100644
--- a/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator.h
+++ b/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator.h
@@ -7,6 +7,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/Vector.h>
@@ -19,7 +25,7 @@ template< typename Mesh,
           typename NonlinearDiffusionOperator,
 	  typename OperatorQ,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class FiniteVolumeNonlinearOperator
 {
  
diff --git a/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator_impl.h b/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator_impl.h
index dc223e6bcbb5399cd7c660c00f5891d1da6a8d34..083160467875cc0e4f40b15c63b7cf59c222a68b 100644
--- a/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator_impl.h
+++ b/src/TNL/Operators/diffusion/FiniteVolumeNonlinearOperator_impl.h
@@ -7,6 +7,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include "FiniteVolumeNonlinearOperator.h"
@@ -124,14 +130,14 @@ operator()( const MeshEntity& entity,
             const Vector& u,
             const Real& time ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const IndexType& cellIndex = entity.getIndex();
    return operatorQ( entity, u, time ) * 
-      ( (  u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, 1 )
-      + (  u[ neighbourEntities.template getEntityIndex<  0, 1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 1 ) 
-      - ( -u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, -1)
-      - ( -u[ neighbourEntities.template getEntityIndex<  0,-1 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, -1) );
+      ( (  u[ neighborEntities.template getEntityIndex<  1, 0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, 1 )
+      + (  u[ neighborEntities.template getEntityIndex<  0, 1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 1 ) 
+      - ( -u[ neighborEntities.template getEntityIndex< -1, 0 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, -1)
+      - ( -u[ neighborEntities.template getEntityIndex<  0,-1 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, -1) );
 }
 
 template< typename MeshReal,
@@ -174,7 +180,7 @@ setMatrixElements( const RealType& time,
                     Matrix& matrix ) const
 {
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
    const RealType aCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< 0, -2 >() / 
                        operatorQ.operator()( entity, u, time, 0, -1 );
    const RealType bCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< -2, 0 >() / 
@@ -188,11 +194,11 @@ setMatrixElements( const RealType& time,
                        operatorQ.operator()( entity, u, time, 1 );
    const RealType eCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< 0, -2 >() / 
                        operatorQ.operator()(  entity, u, time, 0, 1 );
-   matrixRow.setElement( 0, neighbourEntities.template getEntityIndex<  0, -1 >(), aCoef );
-   matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< -1,  0 >(), bCoef );
+   matrixRow.setElement( 0, neighborEntities.template getEntityIndex<  0, -1 >(), aCoef );
+   matrixRow.setElement( 1, neighborEntities.template getEntityIndex< -1,  0 >(), bCoef );
    matrixRow.setElement( 2, entity.getIndex(),                                     cCoef );
-   matrixRow.setElement( 3, neighbourEntities.template getEntityIndex<  1,  0 >(), dCoef );
-   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex<  0,  1 >(), eCoef );
+   matrixRow.setElement( 3, neighborEntities.template getEntityIndex<  1,  0 >(), dCoef );
+   matrixRow.setElement( 4, neighborEntities.template getEntityIndex<  0,  1 >(), eCoef );
 }
 
 template< typename MeshReal,
@@ -227,21 +233,21 @@ operator()( const MeshEntity& entity,
             const Vector& u,
             const Real& time ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const IndexType& cellIndex = entity.getIndex();
    return operatorQ( entity, u, time ) * 
-      ( (u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ]) 
+      ( (u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ]) 
           * mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ( entity, u, time, 1 )
-          + ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()/
+          + ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()/
           operatorQ( entity, u, time, 0, 1 ) 
-          + ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()/
+          + ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()/
           operatorQ( entity, u, time, 0, 0, 1 ) 
-          - ( - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ]  + u[ cellIndex ]) 
+          - ( - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ]  + u[ cellIndex ]) 
           * mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ( entity, u, time, -1)
-          -( - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()
+          -( - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()
           /operatorQ( entity, u, time, 0, -1) 
-          -( - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()
+          -( - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()
           /operatorQ( entity, u, time, 0, 0, -1) );
 }
 
@@ -287,7 +293,7 @@ setMatrixElements( const RealType& time,
                     Matrix& matrix ) const
 {
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
    const RealType aCoef = - tau * operatorQ( entity, u, time ) *
                        mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, -1 );
    const RealType bCoef = - tau * operatorQ( entity, u, time ) * 
@@ -307,13 +313,13 @@ setMatrixElements( const RealType& time,
                        mesh.template getSpaceStepsProducts< 0, -2, 0 >() / operatorQ.operator()( entity, u, time, 0, 1, 0 );
    const RealType gCoef = - tau * operatorQ.operator()( entity, u, time ) * 
                        mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, 1 );
-   matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0,0,-1 >(), aCoef );
-   matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0,-1,0 >(), bCoef );
-   matrixRow.setElement( 2, neighbourEntities.template getEntityIndex< -1,0,0 >(), cCoef );
+   matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0,0,-1 >(), aCoef );
+   matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0,-1,0 >(), bCoef );
+   matrixRow.setElement( 2, neighborEntities.template getEntityIndex< -1,0,0 >(), cCoef );
    matrixRow.setElement( 3, entity.getIndex(),                                     dCoef );
-   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex< 1,0,0 >(),  eCoef );
-   matrixRow.setElement( 5, neighbourEntities.template getEntityIndex< 0,1,0 >(),  fCoef );
-   matrixRow.setElement( 6, neighbourEntities.template getEntityIndex< 0,0,1 >(),  gCoef );
+   matrixRow.setElement( 4, neighborEntities.template getEntityIndex< 1,0,0 >(),  eCoef );
+   matrixRow.setElement( 5, neighborEntities.template getEntityIndex< 0,1,0 >(),  fCoef );
+   matrixRow.setElement( 6, neighborEntities.template getEntityIndex< 0,0,1 >(),  gCoef );
 }
 
 } // namespace Operators
diff --git a/src/TNL/Operators/diffusion/LinearDiffusion.h b/src/TNL/Operators/diffusion/LinearDiffusion.h
index dd38c170daa48b4473c6e08a7a8e775fdc89578d..ff9c05f03238eb5e10869f4a1dc2d8a6cd2d821a 100644
--- a/src/TNL/Operators/diffusion/LinearDiffusion.h
+++ b/src/TNL/Operators/diffusion/LinearDiffusion.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Containers/Vector.h>
@@ -21,7 +27,7 @@ namespace Operators {
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class LinearDiffusion
 {
  
@@ -46,9 +52,9 @@ class LinearDiffusion< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Inde
       typedef Index IndexType;
       typedef ExactLinearDiffusion< 1 > ExactOperatorType;
  
-      static const int Dimensions = MeshType::meshDimensions;
+      static const int Dimension = MeshType::getMeshDimension();
  
-      static constexpr int getMeshDimensions() { return Dimensions; }
+      static constexpr int getDimension() { return Dimension; }
  
       static String getType();
 
@@ -97,9 +103,9 @@ class LinearDiffusion< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Ind
       typedef Index IndexType;
       typedef ExactLinearDiffusion< 2 > ExactOperatorType;
  
-      static const int Dimensions = MeshType::meshDimensions;
+      static const int Dimension = MeshType::getMeshDimension();
  
-      static constexpr int getMeshDimensions() { return Dimensions; }
+      static constexpr int getDimension() { return Dimension; }
 
       static String getType();
 
@@ -147,9 +153,9 @@ class LinearDiffusion< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Ind
       typedef Index IndexType;
       typedef ExactLinearDiffusion< 3 > ExactOperatorType;
 
-      static const int Dimensions = MeshType::meshDimensions;
+      static const int Dimension = MeshType::getMeshDimension();
  
-      static constexpr int getMeshDimensions() { return Dimensions; }
+      static constexpr int getDimension() { return Dimension; }
 
       static String getType();
 
diff --git a/src/TNL/Operators/diffusion/LinearDiffusion_impl.h b/src/TNL/Operators/diffusion/LinearDiffusion_impl.h
index c20e8fa39ffe917ab69511a63894b50f13aac744..83a20829ccc4f46a56eb80b1e474990db23856da 100644
--- a/src/TNL/Operators/diffusion/LinearDiffusion_impl.h
+++ b/src/TNL/Operators/diffusion/LinearDiffusion_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Operators/diffusion/LinearDiffusion.h>
@@ -46,13 +52,13 @@ operator()( const PreimageFunction& u,
             const MeshEntity& entity,
             const Real& time ) 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();
+   static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 1, "Wrong preimage function" );
+   const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
    const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< - 2 >();
-   return ( u[ neighbourEntities.template getEntityIndex< -1 >() ]
+   return ( u[ neighborEntities.template getEntityIndex< -1 >() ]
             - 2.0 * u[ entity.getIndex() ]
-            + u[ neighbourEntities.template getEntityIndex< 1 >() ] ) * hxSquareInverse;
+            + u[ neighborEntities.template getEntityIndex< 1 >() ] ) * hxSquareInverse;
 }
 
 template< typename MeshReal,
@@ -92,15 +98,15 @@ setMatrixElements( const PreimageFunction& u,
                    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();
+   static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 1, "Wrong preimage function" );
+   const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
    const IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
    const RealType lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >();
-   matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1 >(),      - lambdaX );
+   matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(),      - lambdaX );
    matrixRow.setElement( 1, index,                                              2.0 * lambdaX );
-   matrixRow.setElement( 2, neighbourEntities.template getEntityIndex< 1 >(),       - lambdaX );
+   matrixRow.setElement( 2, neighborEntities.template getEntityIndex< 1 >(),       - lambdaX );
 }
 
 template< typename MeshReal,
@@ -151,15 +157,15 @@ operator()( const PreimageFunction& u,
             const EntityType& entity,
             const Real& time ) const
 {
-   static_assert( EntityType::entityDimensions == 2, "Wrong mesh entity dimensions." );
-   static_assert( PreimageFunction::getEntitiesDimensions() == 2, "Wrong preimage function" );
-   const typename EntityType::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   static_assert( EntityType::getEntityDimension() == 2, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 2, "Wrong preimage function" );
+   const typename EntityType::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
    const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
    const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
-   return ( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ]
-          + u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] ) * hxSquareInverse +
-          ( u[ neighbourEntities.template getEntityIndex<  0, -1 >() ]
-          + u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] ) * hySquareInverse
+   return ( u[ neighborEntities.template getEntityIndex< -1,  0 >() ]
+          + u[ neighborEntities.template getEntityIndex<  1,  0 >() ] ) * hxSquareInverse +
+          ( u[ neighborEntities.template getEntityIndex<  0, -1 >() ]
+          + u[ neighborEntities.template getEntityIndex<  0,  1 >() ] ) * hySquareInverse
           - 2.0 * u[ entity.getIndex() ] * ( hxSquareInverse + hySquareInverse );
 }
 
@@ -183,18 +189,18 @@ setMatrixElements( const PreimageFunction& u,
                    Matrix& matrix,
                    Vector& b ) const
 {
-   static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." );
-   static_assert( PreimageFunction::getEntitiesDimensions() == 2, "Wrong preimage function" );
+   static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 2, "Wrong preimage function" );
    const IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
    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 );
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
+   matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -lambdaY );
+   matrixRow.setElement( 1, neighborEntities.template getEntityIndex< -1, 0 >(), -lambdaX );
    matrixRow.setElement( 2, index,                                                        2.0 * ( lambdaX + lambdaY ) );
-   matrixRow.setElement( 3, neighbourEntities.template getEntityIndex< 1, 0 >(),   -lambdaX );
-   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex< 0, 1 >(),   -lambdaY );
+   matrixRow.setElement( 3, neighborEntities.template getEntityIndex< 1, 0 >(),   -lambdaX );
+   matrixRow.setElement( 4, neighborEntities.template getEntityIndex< 0, 1 >(),   -lambdaY );
 }
 
 
@@ -228,18 +234,18 @@ operator()( const PreimageFunction& u,
             const EntityType& entity,
             const Real& time ) const
 {
-   static_assert( EntityType::entityDimensions == 3, "Wrong mesh entity dimensions." );
-   static_assert( PreimageFunction::getEntitiesDimensions() == 3, "Wrong preimage function" );
-   const typename EntityType::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   static_assert( EntityType::getEntityDimension() == 3, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 3, "Wrong preimage function" );
+   const typename EntityType::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
    const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >();
    const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >();
    const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -2 >();
-   return (   u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ]
-            + u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] ) * hxSquareInverse +
-          (   u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ]
-            + u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] ) * hySquareInverse +
-          (   u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ]
-            + u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] ) * hzSquareInverse
+   return (   u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ]
+            + u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] ) * hxSquareInverse +
+          (   u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ]
+            + u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] ) * hySquareInverse +
+          (   u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ]
+            + u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] ) * hzSquareInverse
          - 2.0 * u[ entity.getIndex() ] * ( hxSquareInverse + hySquareInverse + hzSquareInverse );
 }
 
@@ -280,21 +286,21 @@ setMatrixElements( const PreimageFunction& u,
                    Matrix& matrix,
                    Vector& b ) const
 {
-   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();
+   static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == 3, "Wrong preimage function" );
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
    const IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
    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 );
+   matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -lambdaZ );
+   matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -lambdaY );
+   matrixRow.setElement( 2, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -lambdaX );
    matrixRow.setElement( 3, index,                             2.0 * ( lambdaX + lambdaY + lambdaZ ) );
-   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex< 1, 0, 0 >(),   -lambdaX );
-   matrixRow.setElement( 5, neighbourEntities.template getEntityIndex< 0, 1, 0 >(),   -lambdaY );
-   matrixRow.setElement( 6, neighbourEntities.template getEntityIndex< 0, 0, 1 >(),   -lambdaZ );
+   matrixRow.setElement( 4, neighborEntities.template getEntityIndex< 1, 0, 0 >(),   -lambdaX );
+   matrixRow.setElement( 5, neighborEntities.template getEntityIndex< 0, 1, 0 >(),   -lambdaY );
+   matrixRow.setElement( 6, neighborEntities.template getEntityIndex< 0, 0, 1 >(),   -lambdaZ );
 }
 
 } // namespace Operators
diff --git a/src/TNL/Operators/diffusion/NonlinearDiffusion_impl.h b/src/TNL/Operators/diffusion/NonlinearDiffusion_impl.h
index da4b1d281f43fbe6bdc18fe4712a13036bbaa3bd..0dbc269883acadf563cf6fa6f5c28c185e24436f 100644
--- a/src/TNL/Operators/diffusion/NonlinearDiffusion_impl.h
+++ b/src/TNL/Operators/diffusion/NonlinearDiffusion_impl.h
@@ -1,9 +1,25 @@
+/***************************************************************************
+                          NonlinearDiffusion.h  -  description
+                             -------------------
+    begin                : Aug 8, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
 
 #pragma once
 
 #include "NonlinearDiffusion.h"
 #include <TNL/Meshes/Grid.h>
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
+
 namespace TNL {
 namespace Operators {
 
diff --git a/src/TNL/Operators/diffusion/OneSidedMeanCurvature.h b/src/TNL/Operators/diffusion/OneSidedMeanCurvature.h
index f6d2871c199d4c147173171bbb25260fc8f03225..91f9848cbc9bc63faca5538913f1ec4c9a1701b0 100644
--- a/src/TNL/Operators/diffusion/OneSidedMeanCurvature.h
+++ b/src/TNL/Operators/diffusion/OneSidedMeanCurvature.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Operators/Operator.h>
@@ -24,10 +30,10 @@ namespace Operators {
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType,
+          typename Index = typename Mesh::GlobalIndexType,
           bool EvaluateNonlinearityOnFly = false >
 class OneSidedMeanCurvature
-   : public Operator< Mesh, Functions::MeshInteriorDomain, Mesh::getMeshDimensions(), Mesh::getMeshDimensions(), Real, Index >
+   : public Operator< Mesh, Functions::MeshInteriorDomain, Mesh::getMeshDimension(), Mesh::getMeshDimension(), Real, Index >
 {
    public:
  
@@ -37,12 +43,12 @@ class OneSidedMeanCurvature
       typedef Index IndexType;
       typedef FDMGradientNorm< MeshType, ForwardFiniteDifference, RealType, IndexType > GradientNorm;
       typedef FunctionInverseOperator< GradientNorm > NonlinearityOperator;
-      typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimensions(), RealType > NonlinearityMeshFunction;
-      typedef Functions::Analytic::Constant< MeshType::getMeshDimensions(), RealType > NonlinearityBoundaryConditionsFunction;
+      typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimension(), RealType > NonlinearityMeshFunction;
+      typedef Functions::Analytic::Constant< MeshType::getMeshDimension(), RealType > NonlinearityBoundaryConditionsFunction;
       typedef NeumannBoundaryConditions< MeshType, NonlinearityBoundaryConditionsFunction > NonlinearityBoundaryConditions;
       typedef Functions::OperatorFunction< NonlinearityOperator, NonlinearityMeshFunction, NonlinearityBoundaryConditions, EvaluateNonlinearityOnFly > Nonlinearity;
       typedef OneSidedNonlinearDiffusion< Mesh, Nonlinearity, RealType, IndexType > NonlinearDiffusion;
-      typedef ExactMeanCurvature< Mesh::getMeshDimensions(), RealType > ExactOperatorType;
+      typedef ExactMeanCurvature< Mesh::getMeshDimension(), RealType > ExactOperatorType;
       
       OneSidedMeanCurvature( const MeshPointer& meshPointer )
       : nonlinearityOperator( gradientNorm ),
diff --git a/src/TNL/Operators/diffusion/OneSidedNonlinearDiffusion.h b/src/TNL/Operators/diffusion/OneSidedNonlinearDiffusion.h
index 652bf8ba1801f0ea17f0c0881bbe277d08e1f546..b74abe0b06de5898e86679dcd537d9656cbfcc9b 100644
--- a/src/TNL/Operators/diffusion/OneSidedNonlinearDiffusion.h
+++ b/src/TNL/Operators/diffusion/OneSidedNonlinearDiffusion.h
@@ -8,6 +8,11 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
 
 #pragma once
 
@@ -21,7 +26,7 @@ namespace Operators {
 template< typename Mesh,
           typename Nonlinearity,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class OneSidedNonlinearDiffusion
 {
 };
@@ -42,8 +47,8 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 1,MeshReal, Device, MeshIndex >,
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Nonlinearity NonlinearityType;
-      typedef typename MeshType::template MeshEntity< MeshType::getMeshDimensions() > CellType;
-      typedef ExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
+      typedef typename MeshType::template MeshEntity< MeshType::getMeshDimension() > CellType;
+      typedef ExactNonlinearDiffusion< MeshType::getMeshDimension(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
 
       OneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
       : nonlinearity( nonlinearity ){}
@@ -64,12 +69,12 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 1,MeshReal, Device, MeshIndex >,
                        const MeshEntity& entity,
                        const RealType& time = 0.0 ) const
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const typename MeshEntity::MeshType& mesh = entity.getMesh();
          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 >();
+         const IndexType& east = neighborEntities.template getEntityIndex<  1 >();
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >();
          const RealType& u_c = u[ center ];
          const RealType u_x_f = ( u[ east ] - u_c );
          const RealType u_x_b = ( u_c - u[ west ] );
@@ -100,10 +105,10 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 1,MeshReal, Device, MeshIndex >,
                                      Vector& b ) const
       {
          typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const IndexType& center = entity.getIndex();
-         const IndexType& east = neighbourEntities.template getEntityIndex<  1 >();
-         const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+         const IndexType& east = neighborEntities.template getEntityIndex<  1 >();
+         const IndexType& west = neighborEntities.template getEntityIndex< -1 >();
          const RealType lambda_x = tau * entity.getMesh().template getSpaceStepsProducts< -2 >();
          const RealType& nonlinearity_center = this->nonlinearity[ center ];
          const RealType& nonlinearity_west = this->nonlinearity[ west ];
@@ -137,7 +142,7 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 2, MeshReal, Device, MeshIndex >
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Nonlinearity NonlinearityType;
-      typedef ExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
+      typedef ExactNonlinearDiffusion< MeshType::getMeshDimension(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
 
       OneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
       : nonlinearity( nonlinearity ){}
@@ -158,15 +163,15 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 2, MeshReal, Device, MeshIndex >
                        const MeshEntity& entity,
                        const RealType& time = 0.0 ) const
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const typename MeshEntity::MeshType& mesh = entity.getMesh();
          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 >();
-         const IndexType& north = neighbourEntities.template getEntityIndex< 0,  1 >();
-         const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >();
+         const IndexType& east = neighborEntities.template getEntityIndex<  1, 0 >();
+         const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >();
+         const IndexType& north = neighborEntities.template getEntityIndex< 0,  1 >();
+         const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >();
          const RealType& u_c = u[ center ];
          const RealType u_x_f = ( u[ east ] - u_c );
          const RealType u_x_b = ( u_c - u[ west ] );
@@ -200,12 +205,12 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 2, MeshReal, Device, MeshIndex >
                                      Vector& b ) const
       {
          typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const IndexType& center = entity.getIndex();
-         const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0 >();
-         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0 >();
-         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1 >();
-         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1 >();
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0 >();
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >();
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >();
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();
          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 ];
@@ -246,7 +251,7 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 3, MeshReal, Device, MeshIndex >
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Nonlinearity NonlinearityType;
-      typedef ExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
+      typedef ExactNonlinearDiffusion< MeshType::getMeshDimension(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
 
       OneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
       : nonlinearity( nonlinearity ){}
@@ -267,18 +272,18 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 3, MeshReal, Device, MeshIndex >
                        const MeshEntity& entity,
                        const RealType& time = 0.0 ) const
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const typename MeshEntity::MeshType& mesh = entity.getMesh();
          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 >();
-         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >();
-         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >();
-         const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >();
-         const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >();
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >();
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >();
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >();
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >();
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
  
          const RealType& u_c = u[ center ];
          const RealType u_x_f = ( u[ east ] - u_c );
@@ -317,14 +322,14 @@ class OneSidedNonlinearDiffusion< Meshes::Grid< 3, MeshReal, Device, MeshIndex >
                                      Vector& b ) const
       {
          typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const IndexType& center = entity.getIndex();
-         const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0,  0 >();
-         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0,  0 >();
-         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >();
-         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >();
-         const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >();
-         const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >();
+         const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >();
+         const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >();
+         const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >();
+         const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >();
+         const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();
  
  
          const RealType lambda_x = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >();
diff --git a/src/TNL/Operators/euler/CMakeLists.txt b/src/TNL/Operators/euler/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Operators/euler/fvm/CMakeLists.txt b/src/TNL/Operators/euler/fvm/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Operators/euler/fvm/LaxFridrichs.h b/src/TNL/Operators/euler/fvm/LaxFridrichs.h
index 9aa009ea1396322065a3032b00871c84f3b68347..8033c80f97d665cc642bbbf11868a4e44b910273 100644
--- a/src/TNL/Operators/euler/fvm/LaxFridrichs.h
+++ b/src/TNL/Operators/euler/fvm/LaxFridrichs.h
@@ -37,20 +37,20 @@ class LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, Pressu
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename MeshType :: VertexType VertexType;
+   typedef typename MeshType :: PointType PointType;
    typedef typename MeshType :: CoordinatesType CoordinatesType;
 
    LaxFridrichs();
 
    static String getTypeStatic();
 
-   void getExplicitRhs( const IndexType centralVolume,
+   void getExplicitUpdate( const IndexType centralVolume,
                         RealType& rho_t,
                         RealType& rho_u1_t,
                         RealType& rho_u2_t,
                         const RealType& tau ) const;
 
-   void getExplicitRhs( const IndexType centralVolume,
+   void getExplicitUpdate( const IndexType centralVolume,
                         RealType& rho_t,
                         RealType& rho_u1_t,
                         RealType& rho_u2_t,
@@ -106,18 +106,18 @@ class LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeomet
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef typename MeshType :: VertexType VertexType;
+   typedef typename MeshType :: PointType PointType;
    typedef typename MeshType :: CoordinatesType CoordinatesType;
 
    LaxFridrichs();
 
-   void getExplicitRhs( const IndexType centralVolume,
+   void getExplicitUpdate( const IndexType centralVolume,
                         RealType& rho_t,
                         RealType& rho_u1_t,
                         RealType& rho_u2_t,
                         const RealType& tau ) const;
 
-   void getExplicitRhs( const IndexType centralVolume,
+   void getExplicitUpdate( const IndexType centralVolume,
                         RealType& rho_t,
                         RealType& rho_u1_t,
                         RealType& rho_u2_t,
diff --git a/src/TNL/Operators/euler/fvm/LaxFridrichs_impl.h b/src/TNL/Operators/euler/fvm/LaxFridrichs_impl.h
index 684d5c4e1c1febbb0692ecfa8e1f6839bef9009a..b2cc2ff06d267933fbacb78be213a24a8496ef5f 100644
--- a/src/TNL/Operators/euler/fvm/LaxFridrichs_impl.h
+++ b/src/TNL/Operators/euler/fvm/LaxFridrichs_impl.h
@@ -141,20 +141,20 @@ template< typename Real,
           typename Index,
           typename PressureGradient,
           template< int, typename, typename, typename > class GridGeometry >
-void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: getExplicitRhs( const IndexType centralVolume,
+void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: getExplicitUpdate( const IndexType centralVolume,
                                                                                                               RealType& rho_t,
                                                                                                               RealType& rho_u1_t,
                                                                                                               RealType& rho_u2_t,
                                                                                                               const RealType& tau ) const
 {
-   Assert( mesh, std::cerr << "No mesh has been binded with the Lax-Fridrichs scheme." );
-   Assert( pressureGradient, std::cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
+   TNL_ASSERT_TRUE( mesh, "No mesh has been binded with the Lax-Fridrichs scheme." );
+   TNL_ASSERT_TRUE( pressureGradient, "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 -> getElementNeighbor( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbor( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbor( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbor( centralVolume,  0, -1 );
 
    const RealType u1_e = rho_u1[ e ] / regularize( rho[ e ] );
    const RealType u1_w = rho_u1[ w ] / regularize( rho[ w ] );
@@ -168,7 +168,7 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, Pressur
    const RealType u2_w = rho_u2[ w ] / regularize( rho[ w ] );
 
    /****
-    * Get the central volume and its neighbours (east, north, west, south) coordinates
+    * Get the central volume and its neighbors (east, north, west, south) coordinates
     */
    CoordinatesType c_coordinates, e_coordinates, n_coordinates, w_coordinates, s_coordinates;
    this->mesh -> getElementCoordinates( c, c_coordinates );
@@ -190,7 +190,7 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, Pressur
    /****
     * Get the edge normals
     */
-   VertexType e_normal, w_normal, n_normal, s_normal;
+   PointType 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 );
@@ -229,7 +229,7 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, GridGeometry >, Pressur
    /****
     * Compute the pressure gradient
     */
-   VertexType grad_p;
+   PointType grad_p;
    pressureGradient -> getGradient( c, grad_p );
 
    /****
@@ -392,14 +392,14 @@ template< typename Real,
           typename Device,
           typename Index,
           typename PressureGradient >
-void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: getExplicitRhs( const IndexType centralVolume,
+void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: getExplicitUpdate( const IndexType centralVolume,
                                                                                                                           RealType& rho_t,
                                                                                                                           RealType& rho_u1_t,
                                                                                                                           RealType& rho_u2_t,
                                                                                                                           const RealType& tau ) const
 {
-   Assert( mesh, std::cerr << "No mesh has been binded with the Lax-Fridrichs scheme." );
-   Assert( pressureGradient, std::cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
+   TNL_ASSERT_TRUE( mesh, "No mesh has been binded with the Lax-Fridrichs scheme." );
+   TNL_ASSERT_TRUE( pressureGradient, "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();
@@ -407,10 +407,10 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometr
    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 -> getElementNeighbor( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbor( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbor( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbor( centralVolume,  0, -1 );
 
    /****
     * rho_t + ( rho u_1 )_x + ( rho u_2 )_y =  0
@@ -426,7 +426,7 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometr
    /****
     * Compute the pressure gradient
     */
-   VertexType grad_p;
+   PointType grad_p;
    pressureGradient -> getGradient( c, grad_p );
 
    /****
@@ -449,15 +449,15 @@ template< typename Real,
           typename Device,
           typename Index,
           typename PressureGradient >
-void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: getExplicitRhs( const IndexType centralVolume,
+void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: getExplicitUpdate( const IndexType centralVolume,
                                                                                                                           RealType& rho_t,
                                                                                                                           RealType& rho_u1_t,
                                                                                                                           RealType& rho_u2_t,
                                                                                                                           RealType& e_t,
                                                                                                                           const RealType& tau ) const
 {
-   Assert( mesh, std::cerr << "No mesh has been binded with the Lax-Fridrichs scheme." );
-   Assert( pressureGradient, std::cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
+   TNL_ASSERT_TRUE( mesh, "No mesh has been binded with the Lax-Fridrichs scheme." );
+   TNL_ASSERT_TRUE( pressureGradient, "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();
@@ -465,10 +465,10 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometr
    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 -> getElementNeighbor( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbor( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbor( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbor( centralVolume,  0, -1 );
 
    /****
     * rho_t + ( rho u_1 )_x + ( rho u_2 )_y =  0
@@ -484,7 +484,7 @@ void LaxFridrichs< Meshes::Grid< 2, Real, Device, Index, tnlIdenticalGridGeometr
    /****
     * Compute the pressure gradient
     */
-   VertexType grad_p;
+   PointType grad_p;
    pressureGradient -> getGradient( c, grad_p );
 
    /****
diff --git a/src/TNL/Operators/fdm/BackwardFiniteDifference.h b/src/TNL/Operators/fdm/BackwardFiniteDifference.h
index ae88272967acefb399b582582e04c93a171f5dd6..d816499f1e733c4a6cbca7f1a3dc1c0fefe3d320 100644
--- a/src/TNL/Operators/fdm/BackwardFiniteDifference.h
+++ b/src/TNL/Operators/fdm/BackwardFiniteDifference.h
@@ -22,12 +22,12 @@ template< typename Mesh,
           int YDifference = 0,
           int ZDifference = 0,
           typename RealType = typename Mesh::RealType,
-          typename IndexType = typename Mesh::IndexType >
+          typename IndexType = typename Mesh::GlobalIndexType >
 class BackwardFiniteDifference
 {
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename MeshReal,
           typename MeshDevice,
           typename MeshIndex,
@@ -36,19 +36,19 @@ template< int Dimensions,
           int ZDifference,
           typename Real,
           typename Index >
-class BackwardFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
-: public Operator< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
-                      Functions::MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+class BackwardFiniteDifference< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public Operator< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >,
+                      Functions::MeshInteriorDomain, Dimension, Dimension, Real, Index >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex > MeshType;
       typedef Real RealType;
       typedef MeshDevice DeviceType;
       typedef Index IndexType;
-      typedef ExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+      typedef ExactDifference< Dimension, XDifference, YDifference, ZDifference > ExactOperatorType;
  
-      static constexpr int getMeshDimensions() { return Dimensions; }
+      static constexpr int getDimension() { return Dimension; }
  
       static String getType()
       {
@@ -67,7 +67,7 @@ class BackwardFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice,
                               const MeshEntity& entity,
                               const RealType& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+         static_assert( MeshFunction::getEntitiesDimension() == Dimension,
             "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
          const int XDirection = -1 * ( XDifference != 0 );
          const int YDirection = -1 * ( YDifference != 0 );
diff --git a/src/TNL/Operators/fdm/CentralFiniteDifference.h b/src/TNL/Operators/fdm/CentralFiniteDifference.h
index 3d2bbe7a413d72e1883c16a015c85354e540c68f..90c9a5887897dd2664e2936514bb9255089c9e2c 100644
--- a/src/TNL/Operators/fdm/CentralFiniteDifference.h
+++ b/src/TNL/Operators/fdm/CentralFiniteDifference.h
@@ -22,12 +22,12 @@ template< typename Mesh,
           int YDifference = 0,
           int ZDifference = 0,
           typename RealType = typename Mesh::RealType,
-          typename IndexType = typename Mesh::IndexType >
+          typename IndexType = typename Mesh::GlobalIndexType >
 class CentralFiniteDifference
 {
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename MeshReal,
           typename MeshDevice,
           typename MeshIndex,
@@ -36,19 +36,19 @@ template< int Dimensions,
           int ZDifference,
           typename Real,
           typename Index >
-class CentralFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
-: public Operator< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
-                      Functions::MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+class CentralFiniteDifference< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public Operator< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >,
+                      Functions::MeshInteriorDomain, Dimension, Dimension, Real, Index >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex > MeshType;
       typedef Real RealType;
       typedef MeshDevice DeviceType;
       typedef Index IndexType;
-      typedef ExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+      typedef ExactDifference< Dimension, XDifference, YDifference, ZDifference > ExactOperatorType;
  
-      //static constexpr int getMeshDimensions() { return Dimensions; }
+      //static constexpr int getDimension() { return Dimension; }
  
       static String getType()
       {
@@ -68,7 +68,7 @@ class CentralFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice, M
                               const MeshEntity& entity,
                               const RealType& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+         static_assert( MeshFunction::getEntitiesDimension() == Dimension,
             "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
          return FiniteDifferences< MeshType, Real, Index, XDifference, YDifference, ZDifference, 0, 0, 0 >::getValue( u, entity );
       };
diff --git a/src/TNL/Operators/fdm/ExactDifference.h b/src/TNL/Operators/fdm/ExactDifference.h
index 7acf467edfd4f575c62ee8b2b6207fd56b58fd9a..5efffc1b8436a529a4478561fde9326bc323787c 100644
--- a/src/TNL/Operators/fdm/ExactDifference.h
+++ b/src/TNL/Operators/fdm/ExactDifference.h
@@ -13,19 +13,19 @@
 namespace TNL {
 namespace Operators {   
 
-template< int Dimensions,
+template< int Dimension,
           int XDerivative,
           int YDerivative,
           int ZDerivative >
 class ExactDifference
-   : public Functions::Domain< Dimensions, Functions::SpaceDomain >
+   : public Functions::Domain< Dimension, Functions::SpaceDomain >
 {
    public:
  
       static String getType()
       {
          return String( "ExactDifference< " ) +
-            String( Dimensions ) + ", " +
+            String( Dimension ) + ", " +
             String( XDerivative ) + ", " +
             String( YDerivative ) + ", " +
             String( ZDerivative ) + " >";
@@ -35,7 +35,7 @@ class ExactDifference
       __cuda_callable__
       typename Function::RealType operator()(
          const Function& function,
-         const typename Function::VertexType& vertex,
+         const typename Function::PointType& vertex,
          const typename Function::RealType& time = 0 ) const
       {
          return function.template getPartialDerivative<
diff --git a/src/TNL/Operators/fdm/FiniteDifferences_1D.h b/src/TNL/Operators/fdm/FiniteDifferences_1D.h
index 127d454d159ff058ce5e3d7ec5afd7e6b820f228..622e4c4585169179df679ca352610d06dd2ec4e1 100644
--- a/src/TNL/Operators/fdm/FiniteDifferences_1D.h
+++ b/src/TNL/Operators/fdm/FiniteDifferences_1D.h
@@ -66,10 +66,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 1 >()] - u_c ) * hxDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 1 >()] - u_c ) * hxDiv;
       }
 };
 
@@ -93,10 +93,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1 >()] ) * hxDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< -1 >()] ) * hxDiv;
       }
 };
 
@@ -120,10 +120,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 1 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * ( 0.5 * hxDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 1 >() ] -
+                  u[ neighborEntities.template getEntityIndex< -1 >() ] ) * ( 0.5 * hxDiv );
       }
 };
 
@@ -147,12 +147,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -173,12 +173,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< -2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< -2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -199,12 +199,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 1 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 1 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
       }
 };
 
diff --git a/src/TNL/Operators/fdm/FiniteDifferences_2D.h b/src/TNL/Operators/fdm/FiniteDifferences_2D.h
index d287b50d210d36abdbe9d373bc4b1567aa70968c..4ea67b93159038745e137e0c6decc17c234e720e 100644
--- a/src/TNL/Operators/fdm/FiniteDifferences_2D.h
+++ b/src/TNL/Operators/fdm/FiniteDifferences_2D.h
@@ -66,10 +66,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 1, 0 >()] - u_c ) * hxDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 1, 0 >()] - u_c ) * hxDiv;
       }
 };
 
@@ -90,10 +90,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 1 >()] - u_c ) * hyDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 0, 1 >()] - u_c ) * hyDiv;
       }
 };
 
@@ -117,10 +117,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;
       }
 };
 
@@ -141,10 +141,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
       }
 };
 
@@ -168,10 +168,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * ( 0.5 * hxDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 1, 0 >() ] -
+                  u[ neighborEntities.template getEntityIndex< -1, 0 >() ] ) * ( 0.5 * hxDiv );
       }
 };
 
@@ -192,10 +192,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * ( 0.5 * hyDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 0,  1 >() ] -
+                  u[ neighborEntities.template getEntityIndex< 0, -1 >() ] ) * ( 0.5 * hyDiv );
       }
 };
 
@@ -220,12 +220,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2,0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 2, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 2, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -246,12 +246,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< -2, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< -2, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -272,12 +272,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex<  1, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -298,12 +298,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, 2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, 1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -324,12 +324,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, -2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, -2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, -1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -351,12 +351,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
          const Real& hySquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0,  1 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * hySquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, -1 >() ] ) * hySquareDiv;
       }
 };
 
diff --git a/src/TNL/Operators/fdm/FiniteDifferences_3D.h b/src/TNL/Operators/fdm/FiniteDifferences_3D.h
index 569a1c7645e4bf5904875ac208dab390c601050d..895aeaddac1be89b57b308becf80b27cd9576c4d 100644
--- a/src/TNL/Operators/fdm/FiniteDifferences_3D.h
+++ b/src/TNL/Operators/fdm/FiniteDifferences_3D.h
@@ -33,10 +33,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >()] - u_c ) * hxDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 1, 0, 0 >()] - u_c ) * hxDiv;
       }
 };
 
@@ -57,10 +57,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >()] - u_c ) * hyDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 0, 1, 0 >()] - u_c ) * hyDiv;
       }
 };
 
@@ -81,10 +81,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >()] - u_c ) * hzDiv;
+         return ( u[ neighborEntities.template getEntityIndex< 0, 0, 1 >()] - u_c ) * hzDiv;
       }
 };
 
@@ -108,10 +108,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >()] ) * hxDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< -1, 0, 0 >()] ) * hxDiv;
       }
 };
 
@@ -132,10 +132,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >()] ) * hyDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< 0, -1, 0 >()] ) * hyDiv;
       }
 };
 
@@ -156,10 +156,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >()] ) * hzDiv;
+         return ( u_c - u[ neighborEntities.template getEntityIndex< 0, 0, -1 >()] ) * hzDiv;
       }
 };
 
@@ -183,10 +183,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * ( 0.5 * hxDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] -
+                  u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ] ) * ( 0.5 * hxDiv );
       }
 };
 
@@ -207,10 +207,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * ( 0.5 * hyDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] -
+                  u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ] ) * ( 0.5 * hyDiv );
       }
 };
 
@@ -231,10 +231,10 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] -
-                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * ( 0.5 * hzDiv );
+         return ( u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] -
+                  u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ] ) * ( 0.5 * hzDiv );
       }
 };
 
@@ -258,12 +258,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 2, 0, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 2, 0, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -284,12 +284,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< -2, 0, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< -2, 0, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -310,12 +310,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex<  1, 0, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex<  1, 0, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -336,12 +336,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 2, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, 2, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -362,12 +362,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, -2, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, -2, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -388,12 +388,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hySquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0,  1, 0 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0,  1, 0 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hySquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hySquareDiv;
       }
 };
 
@@ -414,12 +414,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, 0, 2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -440,12 +440,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, -2 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, 0, -2 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hxSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hxSquareDiv;
       }
 };
 
@@ -466,12 +466,12 @@ class FiniteDifferences<
       static Real getValue( const MeshFunction& u,
                             const MeshEntity& entity )
       {
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
          const Real& hzSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
          const Real& u_c = u[ entity.getIndex() ];
-         return ( u[ neighbourEntities.template getEntityIndex< 0, 0,  1 >() ] -
+         return ( u[ neighborEntities.template getEntityIndex< 0, 0,  1 >() ] -
                   2.0 * u_c +
-                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hzSquareDiv;
+                  u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hzSquareDiv;
       }
 };
 
diff --git a/src/TNL/Operators/fdm/ForwardFiniteDifference.h b/src/TNL/Operators/fdm/ForwardFiniteDifference.h
index 8039f1ee60ca5c5c9f2f627e15df27fb10dad5c3..9c75e05dadd03213494d1229fe814771ca0f540d 100644
--- a/src/TNL/Operators/fdm/ForwardFiniteDifference.h
+++ b/src/TNL/Operators/fdm/ForwardFiniteDifference.h
@@ -23,12 +23,12 @@ template< typename Mesh,
           int YDifference = 0,
           int ZDifference = 0,
           typename RealType = typename Mesh::RealType,
-          typename IndexType = typename Mesh::IndexType >
+          typename IndexType = typename Mesh::GlobalIndexType >
 class ForwardFiniteDifference
 {
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename MeshReal,
           typename MeshDevice,
           typename MeshIndex,
@@ -37,19 +37,19 @@ template< int Dimensions,
           int ZDifference,
           typename Real,
           typename Index >
-class ForwardFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
-: public Operator< Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
-                      Functions::MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+class ForwardFiniteDifference< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public Operator< Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex >,
+                      Functions::MeshInteriorDomain, Dimension, Dimension, Real, Index >
 {
    public:
  
-      typedef Meshes::Grid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Meshes::Grid< Dimension, MeshReal, MeshDevice, MeshIndex > MeshType;
       typedef Real RealType;
       typedef MeshDevice DeviceType;
       typedef Index IndexType;
-      typedef ExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+      typedef ExactDifference< Dimension, XDifference, YDifference, ZDifference > ExactOperatorType;
  
-      static constexpr int getMeshDimensions() { return Dimensions; }
+      static constexpr int getDimension() { return Dimension; }
  
       static String getType()
       {
@@ -69,7 +69,7 @@ class ForwardFiniteDifference< Meshes::Grid< Dimensions, MeshReal, MeshDevice, M
                               const MeshEntity& entity,
                               const RealType& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+         static_assert( MeshFunction::getEntitiesDimension() == Dimension,
             "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
          const int XDirection = 1 * ( XDifference != 0 );
          const int YDirection = 1 * ( YDifference != 0 );
diff --git a/src/TNL/Operators/geometric/CoFVMGradientNorm.h b/src/TNL/Operators/geometric/CoFVMGradientNorm.h
index af7c8c75de76a693ff4a19c97cf92291d6edf245..0380ecc223f8b1556cf379bfb2dd64a1197ae576 100644
--- a/src/TNL/Operators/geometric/CoFVMGradientNorm.h
+++ b/src/TNL/Operators/geometric/CoFVMGradientNorm.h
@@ -20,36 +20,36 @@ namespace TNL {
 namespace Operators {   
 
 template< typename Mesh,
-          int MeshEntityDimensions = Mesh::getMeshDimensions(),
+          int MeshEntityDimension = Mesh::getMeshDimension(),
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class CoFVMGradientNorm
 {
 };
 
-template< int MeshDimensions,
+template< int MeshDimension,
           typename MeshReal,
           typename Device,
           typename MeshIndex,
           typename Real,
           typename Index >
-class CoFVMGradientNorm< Meshes::Grid< MeshDimensions, MeshReal, Device, MeshIndex >, MeshDimensions, Real, Index >
+class CoFVMGradientNorm< Meshes::Grid< MeshDimension, MeshReal, Device, MeshIndex >, MeshDimension, Real, Index >
 : public OperatorComposition<
-   MeshEntitiesInterpolants< Meshes::Grid< MeshDimensions, MeshReal, Device, MeshIndex >,
-                                MeshDimensions - 1,
-                                MeshDimensions >,
-   CoFVMGradientNorm< Meshes::Grid< MeshDimensions, MeshReal, Device, MeshIndex >, MeshDimensions - 1, Real, Index > >
+   MeshEntitiesInterpolants< Meshes::Grid< MeshDimension, MeshReal, Device, MeshIndex >,
+                                MeshDimension - 1,
+                                MeshDimension >,
+   CoFVMGradientNorm< Meshes::Grid< MeshDimension, MeshReal, Device, MeshIndex >, MeshDimension - 1, Real, Index > >
 {
    public:
-      typedef Meshes::Grid< MeshDimensions, MeshReal, Device, MeshIndex > MeshType;
+      typedef Meshes::Grid< MeshDimension, MeshReal, Device, MeshIndex > MeshType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
       typedef Index IndexType;
-      typedef CoFVMGradientNorm< MeshType, MeshDimensions - 1, Real, Index > InnerOperator;
-      typedef MeshEntitiesInterpolants< MeshType, MeshDimensions - 1, MeshDimensions > OuterOperator;
+      typedef CoFVMGradientNorm< MeshType, MeshDimension - 1, Real, Index > InnerOperator;
+      typedef MeshEntitiesInterpolants< MeshType, MeshDimension - 1, MeshDimension > OuterOperator;
       typedef OperatorComposition< OuterOperator, InnerOperator > BaseType;
-      typedef ExactGradientNorm< MeshDimensions, RealType > ExactOperatorType;
+      typedef ExactGradientNorm< MeshDimension, RealType > ExactOperatorType;
       typedef SharedPointer< MeshType > MeshPointer;
          
       CoFVMGradientNorm( const OuterOperator& outerOperator,
@@ -62,7 +62,7 @@ class CoFVMGradientNorm< Meshes::Grid< MeshDimensions, MeshReal, Device, MeshInd
       {
          return String( "CoFVMGradientNorm< " ) +
             MeshType::getType() + ", " +
-            String( MeshDimensions ) + ", " +
+            String( MeshDimension ) + ", " +
            TNL::getType< Real >() + ", " +
            TNL::getType< Index >() + " >";
       }
@@ -72,8 +72,8 @@ class CoFVMGradientNorm< Meshes::Grid< MeshDimensions, MeshReal, Device, MeshInd
          this->getInnerOperator().setEps( eps );
       }
  
-      static constexpr int getPreimageEntitiesDimensions() { return MeshDimensions; };
-      static constexpr int getImageEntitiesDimensions() { return MeshDimensions; };
+      static constexpr int getPreimageEntitiesDimension() { return MeshDimension; };
+      static constexpr int getImageEntitiesDimension() { return MeshDimension; };
 
 };
 
@@ -94,8 +94,8 @@ class CoFVMGradientNorm< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, 0, Real,
    typedef Index IndexType;
    typedef ExactGradientNorm< 1, RealType > ExactOperatorType;
  
-   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
-   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   constexpr static int getPreimageEntitiesDimension() { return MeshType::getMeshDimension(); };
+   constexpr static int getImageEntitiesDimension() { return MeshType::getMeshDimension() - 1; };
  
    CoFVMGradientNorm()
    : epsSquare( 0.0 ){}
@@ -114,15 +114,15 @@ class CoFVMGradientNorm< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, 0, Real,
                     const MeshEntity& entity,
                     const Real& time = 0.0 ) const
    {
-      static_assert( MeshFunction::getDimensions() == 1,
+      static_assert( MeshFunction::getMeshDimension() == 1,
          "The mesh function u must be stored on mesh cells.." );
-      static_assert( MeshEntity::getDimensions() == 0,
+      static_assert( MeshEntity::getMeshDimension() == 0,
          "The complementary finite volume gradient norm may be evaluated only on faces." );
-      const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.template getNeighbourEntities< 1 >();
+      const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.template getNeighborEntities< 1 >();
  
       const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
-      const RealType& u_x = ( u[ neighbourEntities.template getEntityIndex<  1 >() ] -
-                              u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxDiv;
+      const RealType& u_x = ( u[ neighborEntities.template getEntityIndex<  1 >() ] -
+                              u[ neighborEntities.template getEntityIndex< -1 >() ] ) * hxDiv;
       return ::sqrt( this->epsSquare + ( u_x * u_x ) );
    }
  
@@ -154,8 +154,8 @@ class CoFVMGradientNorm< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real
    typedef Index IndexType;
    typedef ExactGradientNorm< 2, RealType > ExactOperatorType;
  
-   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
-   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   constexpr static int getPreimageEntitiesDimension() { return MeshType::getMeshDimension(); };
+   constexpr static int getImageEntitiesDimension() { return MeshType::getMeshDimension() - 1; };
  
    CoFVMGradientNorm()
    : epsSquare( 0.0 ){}
@@ -176,41 +176,41 @@ class CoFVMGradientNorm< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real
                     const MeshEntity& entity,
                     const Real& time = 0.0 ) const
    {
-      static_assert( MeshFunction::getDimensions() == 2,
+      static_assert( MeshFunction::getMeshDimension() == 2,
          "The mesh function u must be stored on mesh cells.." );
-      static_assert( MeshEntity::getDimensions() == 1,
+      static_assert( MeshEntity::getMeshDimension() == 1,
          "The complementary finite volume gradient norm may be evaluated only on faces." );
-      const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.template getNeighbourEntities< 2 >();
+      const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.template getNeighborEntities< 2 >();
       const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
       const RealType& hyDiv = entity.getMesh().template getSpaceStepsProducts<  0, -1 >();
       if( entity.getOrientation().x() != 0.0 )
       {
          const RealType u_x =
-            ( u[ neighbourEntities.template getEntityIndex<  1, 0 >()] -
-              u[ neighbourEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1, 0 >()] -
+              u[ neighborEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;
          RealType u_y;
          if( entity.getCoordinates().y() > 0 )
          {
             if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
                u_y = 0.25 *
-                  ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-                    u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
-                    u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
-                    u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
+                  ( u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+                    u[ neighborEntities.template getEntityIndex< -1,  1 >() ] -
+                    u[ neighborEntities.template getEntityIndex<  1, -1 >() ] -
+                    u[ neighborEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
             else // if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
                u_y = 0.5 *
-                  ( u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] +
-                    u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] -
-                    u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
-                    u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
+                  ( u[ neighborEntities.template getEntityIndex<  1,  0 >() ] +
+                    u[ neighborEntities.template getEntityIndex< -1,  0 >() ] -
+                    u[ neighborEntities.template getEntityIndex<  1, -1 >() ] -
+                    u[ neighborEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
          }
          else // if( entity.getCoordinates().y() > 0 )
          {
             u_y = 0.5 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-                 u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] ) * hyDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+                 u[ neighborEntities.template getEntityIndex< -1,  1 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1,  0 >() ] ) * hyDiv;
          }
          return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y );
       }
@@ -219,28 +219,28 @@ class CoFVMGradientNorm< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real
       {
          if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
             u_x = 0.25 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  1, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
          else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
             u_x = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  0, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
       }
       else // if( entity.getCoordinates().x() > 0 )
       {
          u_x = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  1, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1 >() ] ) * hxDiv;
       }
       const RealType u_y =
-         ( u[ neighbourEntities.template getEntityIndex< 0,  1 >()] -
-           u[ neighbourEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
+         ( u[ neighborEntities.template getEntityIndex< 0,  1 >()] -
+           u[ neighborEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
       return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y );
    }
  
@@ -272,8 +272,8 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
    typedef Index IndexType;
    typedef ExactGradientNorm< 3, RealType > ExactOperatorType;
  
-   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
-   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   constexpr static int getPreimageEntitiesDimension() { return MeshType::getMeshDimension(); };
+   constexpr static int getImageEntitiesDimension() { return MeshType::getMeshDimension() - 1; };
  
    CoFVMGradientNorm()
    : epsSquare( 0.0 ){}
@@ -292,47 +292,47 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
                     const MeshEntity& entity,
                     const Real& time = 0.0 ) const
    {
-      static_assert( MeshFunction::getDimensions() == 3,
+      static_assert( MeshFunction::getMeshDimension() == 3,
          "The mesh function u must be stored on mesh cells.." );
-      static_assert( MeshEntity::getDimensions() == 2,
+      static_assert( MeshEntity::getMeshDimension() == 2,
          "The complementary finite volume gradient norm may be evaluated only on faces." );
-      const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.template getNeighbourEntities< 3 >();
+      const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.template getNeighborEntities< 3 >();
       const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >();
       const RealType& hyDiv = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >();
       const RealType& hzDiv = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >();
       if( entity.getOrientation().x() != 0.0 )
       {
          const RealType u_x =
-            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >()] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >()] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  0,  0 >()] -
+              u[ neighborEntities.template getEntityIndex< -1,  0,  0 >()] ) * hxDiv;
          RealType u_y;
          if( entity.getCoordinates().y() > 0 )
          {
             if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
             {
                u_y = 0.25 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  1,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex< -1,  1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  1, -1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
             }
             else // if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
             {
                u_y = 0.5 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  1, -1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
 
             }
          }
          else // if( entity.getCoordinates().y() > 0 )
          {
             u_y = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] +
-              u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hyDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  1,  0 >() ] +
+              u[ neighborEntities.template getEntityIndex< -1,  1,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hyDiv;
 
          }
          RealType u_z;
@@ -341,27 +341,27 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
             if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
             {
                u_z = 0.25 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] +
-                 u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  0,  1 >() ] +
+                 u[ neighborEntities.template getEntityIndex< -1,  0,  1 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  1,  0, -1 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
             }
             else //if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
             {
                u_z = 0.5 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  1,  0, -1 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
             }
          }
          else //if( entity.getCoordinates().z() > 0 )
          {
             u_z = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hzDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  0,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex< -1,  0,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hzDiv;
          }
          return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
       }
@@ -373,58 +373,58 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
             if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
             {
                u_x = 0.25 *
-               ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
+               ( u[ neighborEntities.template getEntityIndex<  1,  1,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex<  1, -1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1,  1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
             }
             else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
             {
                u_x = 0.5 *
-               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
+               ( u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1,  1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
             }
          }
          else // if( entity.getCoordinates().x() > 0 )
          {
             u_x = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  1,  0 >() ] +
+              u[ neighborEntities.template getEntityIndex<  1, -1,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hxDiv;
          }
          const RealType u_y =
-            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >()] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >()] ) * hyDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  1,  0 >()] -
+              u[ neighborEntities.template getEntityIndex<  0, -1,  0 >()] ) * hyDiv;
          RealType u_z;
          if( entity.getCoordinates().z() > 0 )
          {
             if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
             {
                u_z = 0.25 *
-               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] +
-                 u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
+               ( u[ neighborEntities.template getEntityIndex<  0,  1,  1 >() ] +
+                 u[ neighborEntities.template getEntityIndex<  0, -1,  1 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  0,  1, -1 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
             }
             else // if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
             {
                u_z = 0.5 *
-               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] +
-                 u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
-                 u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
+               ( u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] +
+                 u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  0,  1, -1 >() ] -
+                 u[ neighborEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
             }
          }
          else // if( entity.getCoordinates().z() > 0 )
          {
             u_z = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hzDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  1,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  0, -1,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hzDiv;
          }
          return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
       }
@@ -434,28 +434,28 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
          if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
          {
             u_x = 0.25 *
-            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  1,  0,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  1,  0, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
          }
          else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
          {
             u_x = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
 
          }
       }
       else // if( entity.getCoordinates().x() > 0 )
       {
          u_x = 0.5 *
-         ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] +
-           u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
-           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] -
-           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hxDiv;
+         ( u[ neighborEntities.template getEntityIndex<  1,  0,  1 >() ] +
+           u[ neighborEntities.template getEntityIndex<  1,  0, -1 >() ] -
+           u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] -
+           u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hxDiv;
       }
       RealType u_y;
       if( entity.getCoordinates().y() > 0 )
@@ -463,31 +463,31 @@ class CoFVMGradientNorm< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real
          if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
          {
             u_y = 0.25 *
-            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  1,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  0,  1, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
          }
          else //if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
          {
             u_y = 0.5 *
-            ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] +
-              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
-              u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
+            ( u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] +
+              u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1,  1 >() ] -
+              u[ neighborEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
          }
       }
       else //if( entity.getCoordinates().y() > 0 )
       {
          u_y = 0.5 *
-         ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] +
-           u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
-           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] -
-           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hyDiv;
+         ( u[ neighborEntities.template getEntityIndex<  0,  1,  1 >() ] +
+           u[ neighborEntities.template getEntityIndex<  0,  1, -1 >() ] -
+           u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] -
+           u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hyDiv;
       }
       const RealType u_z =
-         ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >()] -
-           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >()] ) * hzDiv;
+         ( u[ neighborEntities.template getEntityIndex<  0,  0,  1 >()] -
+           u[ neighborEntities.template getEntityIndex<  0,  0, -1 >()] ) * hzDiv;
       return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
    }
  
diff --git a/src/TNL/Operators/geometric/ExactGradientNorm.h b/src/TNL/Operators/geometric/ExactGradientNorm.h
index 0de3d0c6488686fbcc80273e2b8d91284df55d77..cf7e3384820be1c2e8628fe655211037c6dde1dd 100644
--- a/src/TNL/Operators/geometric/ExactGradientNorm.h
+++ b/src/TNL/Operators/geometric/ExactGradientNorm.h
@@ -10,15 +10,13 @@
 
 #pragma once
 
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Functions/Domain.h>
 
 namespace TNL {
 namespace Operators {   
 
-template< int Dimensions,
+template< int Dimension,
           typename Real = double >
 class ExactGradientNorm
 {};
@@ -49,7 +47,7 @@ class ExactGradientNorm< 1, Real >
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -64,7 +62,7 @@ class ExactGradientNorm< 1, Real >
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
@@ -117,7 +115,7 @@ class ExactGradientNorm< 2, Real >
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -133,7 +131,7 @@ class ExactGradientNorm< 2, Real >
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
@@ -191,7 +189,7 @@ class ExactGradientNorm< 3, Real >
       __cuda_callable__
       typename Function::RealType
          operator()( const Function& function,
-                     const typename Function::VertexType& v,
+                     const typename Function::PointType& v,
                      const typename Function::RealType& time = 0.0 ) const
       {
          typedef typename Function::RealType RealType;
@@ -208,7 +206,7 @@ class ExactGradientNorm< 3, Real >
       __cuda_callable__
       typename Function::RealType
          getPartialDerivative( const Function& function,
-                               const typename Function::VertexType& v,
+                               const typename Function::PointType& v,
                                const typename Function::RealType& time = 0.0 ) const
       {
          static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
diff --git a/src/TNL/Operators/geometric/FDMGradientNorm.h b/src/TNL/Operators/geometric/FDMGradientNorm.h
index d574b90123835169e4e390d7a93c04f758f114ad..a5eb4536317a0ff5258a681585f67557ff029d59 100644
--- a/src/TNL/Operators/geometric/FDMGradientNorm.h
+++ b/src/TNL/Operators/geometric/FDMGradientNorm.h
@@ -20,7 +20,7 @@ namespace Operators {
 template< typename Mesh,
           template< typename, int, int, int, typename, typename > class DifferenceOperatorTemplate = ForwardFiniteDifference,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class FDMGradientNorm
 {
 };
diff --git a/src/TNL/Operators/geometric/TwoSidedGradientNorm.h b/src/TNL/Operators/geometric/TwoSidedGradientNorm.h
index 9d78daa5da338ec2e435ec0afc8656e819a3920d..2d86167b1c1ee3a9466635c2605931248d80eb56 100644
--- a/src/TNL/Operators/geometric/TwoSidedGradientNorm.h
+++ b/src/TNL/Operators/geometric/TwoSidedGradientNorm.h
@@ -20,7 +20,7 @@ namespace Operators {
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class TwoSidedGradientNorm
 {
 };
diff --git a/src/TNL/Operators/interpolants/MeshEntitiesInterpolants.h b/src/TNL/Operators/interpolants/MeshEntitiesInterpolants.h
index 31207e35e80292fa44717290dec5b4eab2f3082f..ca9381d1f418e1a033d39c4619678b94856afc63 100644
--- a/src/TNL/Operators/interpolants/MeshEntitiesInterpolants.h
+++ b/src/TNL/Operators/interpolants/MeshEntitiesInterpolants.h
@@ -17,7 +17,7 @@ namespace TNL {
 namespace Operators {   
 
 template< typename Mesh,
-          int InEntityDimensions,
+          int InEntityDimension,
           int OutEntityDimenions >
 class MeshEntitiesInterpolants
 {
@@ -42,16 +42,16 @@ class MeshEntitiesInterpolants< Meshes::Grid< 1, Real, Device, Index >, 1, 0 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntityDimensions() == 1,
+         static_assert( MeshFunction::getEntityDimension() == 1,
             "Mesh function must be defined on cells." );
 
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();
  
-         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] +
-                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
+         return 0.5 * ( u[ neighborEntities.template getEntityIndex< -1 >() ] +
+                        u[ neighborEntities.template getEntityIndex<  1 >() ] );
       }
 };
 
@@ -74,16 +74,16 @@ class MeshEntitiesInterpolants< Meshes::Grid< 1, Real, Device, Index >, 0, 1 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == 0,
+         static_assert( MeshFunction::getEntitiesDimension() == 0,
             "Mesh function must be defined on vertices (or faces in case on 1D grid)." );
  
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.template getNeighbourEntities< 0 >();
+         const typename MeshEntity::template NeighborEntities< 0 >& neighborEntities = entity.template getNeighborEntities< 0 >();
  
-         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] +
-                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
+         return 0.5 * ( u[ neighborEntities.template getEntityIndex< -1 >() ] +
+                        u[ neighborEntities.template getEntityIndex<  1 >() ] );
       }
 };
 
@@ -106,20 +106,20 @@ class MeshEntitiesInterpolants< Meshes::Grid< 2, Real, Device, Index >, 2, 1 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntityDimensions() == 2,
+         static_assert( MeshFunction::getEntityDimension() == 2,
             "Mesh function must be defined on cells." );
  
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
  
          if( entity.getOrientation().x() == 1.0 )
-            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] +
-                           u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] );
+            return 0.5 * ( u[ neighborEntities.template getEntityIndex< -1, 0 >() ] +
+                           u[ neighborEntities.template getEntityIndex<  1, 0 >() ] );
          else
-            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] +
-                           u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] );
+            return 0.5 * ( u[ neighborEntities.template getEntityIndex< 0, -1 >() ] +
+                           u[ neighborEntities.template getEntityIndex< 0,  1 >() ] );
       }
 };
 
@@ -142,18 +142,18 @@ class MeshEntitiesInterpolants< Meshes::Grid< 2, Real, Device, Index >, 2, 0 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntityDimensions() == 2,
+         static_assert( MeshFunction::getEntityDimension() == 2,
             "Mesh function must be defined on cells." );
  
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
  
-         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
+         return 0.25 * ( u[ neighborEntities.template getEntityIndex< -1,  1 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+                         u[ neighborEntities.template getEntityIndex< -1, -1 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  1, -1 >() ] );
       }
 };
 
@@ -176,18 +176,18 @@ class MeshEntitiesInterpolants< Meshes::Grid< 2, Real, Device, Index >, 1, 2 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == 1,
+         static_assert( MeshFunction::getEntitiesDimension() == 1,
             "Mesh function must be defined on faces." );
  
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.template getNeighbourEntities< 1 >();
+         const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.template getNeighborEntities< 1 >();
  
-         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] );
+         return 0.25 * ( u[ neighborEntities.template getEntityIndex< -1,  0 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  1,  0 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  0,  1 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  0, -1 >() ] );
       }
 };
 
@@ -210,18 +210,18 @@ class MeshEntitiesInterpolants< Meshes::Grid< 2, Real, Device, Index >, 0, 2 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntityDimensions() == 1,
+         static_assert( MeshFunction::getEntityDimension() == 1,
             "Mesh function must be defined on vertices." );
 
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 0 >& neighborEntities = entity.getNeighborEntities();
  
-         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] +
-                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
+         return 0.25 * ( u[ neighborEntities.template getEntityIndex< -1,  1 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  1,  1 >() ] +
+                         u[ neighborEntities.template getEntityIndex< -1, -1 >() ] +
+                         u[ neighborEntities.template getEntityIndex<  1, -1 >() ] );
       }
 };
 
@@ -244,23 +244,23 @@ class MeshEntitiesInterpolants< Meshes::Grid< 3, Real, Device, Index >, 3, 2 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntityDimensions() == 3,
+         static_assert( MeshFunction::getEntityDimension() == 3,
             "Mesh function must be defined on cells." );
 
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
  
          if( entity.getOrientation().x() == 1.0 )
-            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] +
-                           u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] );
+            return 0.5 * ( u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] +
+                           u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] );
          if( entity.getOrientation().y() == 1.0 )
-            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] +
-                           u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] );
+            return 0.5 * ( u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] +
+                           u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] );
          else
-            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] +
-                           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );
+            return 0.5 * ( u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] +
+                           u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] );
       }
 };
 
@@ -283,20 +283,20 @@ class MeshEntitiesInterpolants< Meshes::Grid< 3, Real, Device, Index >, 2, 3 >
                        const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         static_assert( MeshFunction::getEntitiesDimensions() == 2,
+         static_assert( MeshFunction::getEntitiesDimension() == 2,
             "Mesh function must be defined on faces." );
 
          static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
             "The mesh entity belongs to other mesh type then the interpolants." );
  
-         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.template getNeighbourEntities< 2 >();
+         const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.template getNeighborEntities< 2 >();
  
-         return 1.0 / 6.0 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] +
-                              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] +
-                              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] +
-                              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] +
-                              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] +
-                              u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );
+         return 1.0 / 6.0 * ( u[ neighborEntities.template getEntityIndex< -1,  0,  0 >() ] +
+                              u[ neighborEntities.template getEntityIndex<  1,  0,  0 >() ] +
+                              u[ neighborEntities.template getEntityIndex<  0, -1,  0 >() ] +
+                              u[ neighborEntities.template getEntityIndex<  0,  1,  0 >() ] +
+                              u[ neighborEntities.template getEntityIndex<  0,  0, -1 >() ] +
+                              u[ neighborEntities.template getEntityIndex<  0,  0,  1 >() ] );
       }
 };
 
diff --git a/src/TNL/Operators/operator-Q/CMakeLists.txt b/src/TNL/Operators/operator-Q/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ.h b/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ.h
index 5cf59f1766f8accd727b173dd1dc134bd166f06b..7f145198f049c2062e0e53d33b215e0fe8c0a3b8 100644
--- a/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ.h
+++ b/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ.h
@@ -19,7 +19,7 @@ namespace Operators {
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType,
+          typename Index = typename Mesh::GlobalIndexType,
           int Precomputation = 0 > 
 class tnlFiniteVolumeOperatorQ
 {
diff --git a/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h b/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h
index 4338bbe680660c5a0c1edff4a00d0b7b7feeb01c..0fae70006b3b9f69c8157cfcf2ad5538489b8f1d 100644
--- a/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h
+++ b/src/TNL/Operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h
@@ -242,7 +242,7 @@ void
 tnlFiniteVolumeOperatorQ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
 update( const MeshType& mesh, const RealType& time )
 {
-    CoordinatesType dimensions = mesh.getDimensions();
+    CoordinatesType dimensions = mesh.getMeshDimension();
     CoordinatesType coordinates;
     
     for( coordinates.x()=1; coordinates.x() < dimensions.x()-1; coordinates.x()++ )
@@ -270,37 +270,37 @@ boundaryDerivative(
    const IndexType& dy,
    const IndexType& dz ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();      
    const IndexType& cellIndex = entity.getIndex();
     if ( ( AxeX == 1 ) && ( AxeY == 0 ) && ( AxeZ == 0 ) )
     {
         if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] );
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ neighborEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] );
         if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ cellIndex ] - u[ neighborEntities.template getEntityIndex< -1,0 >() ] );
         if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,1 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,1 >() ] - u[ neighborEntities.template getEntityIndex< -1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,1 >() ] );
         if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,-1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,-1 >() ] - u[ neighborEntities.template getEntityIndex< -1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,-1 >() ] );
     }
     if ( ( AxeX == 0 ) && ( AxeY == 1 ) && ( AxeZ == 0 ) )
     {
         if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] );
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ neighborEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] );
         if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ cellIndex ] - u[ neighborEntities.template getEntityIndex< 0,-1 >() ] );
         if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 1,-1 >() ] );
         if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< -1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< -1,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,-1 >() ] );
     }
     return 0.0;
 }
@@ -321,14 +321,14 @@ operator()( const MeshEntity& entity,
           const IndexType& dy,
           const IndexType& dz ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const IndexType& cellIndex = entity.getIndex();
     if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 0 ) )
-        return ::sqrt( this->eps + ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] ) * 
-                ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] )
-                * mesh.template getSpaceStepsProducts< 0, -1 >() * mesh.template getSpaceStepsProducts< 0, -1 >() + ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) 
-                * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0 >() * mesh.template getSpaceStepsProducts< -1, 0 >() );
+        return ::sqrt( this->eps + ( u[ neighborEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] ) * 
+                ( u[ neighborEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] )
+                * mesh.template getSpaceStepsProducts< 0, -1 >() * mesh.template getSpaceStepsProducts< 0, -1 >() + ( u[ neighborEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighborEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0 >() * mesh.template getSpaceStepsProducts< -1, 0 >() );
     if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
         return ::sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 1, 0 ) * 
                this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 1, 0 ) + 
@@ -437,8 +437,7 @@ tnlFiniteVolumeOperatorQ< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real,
 bind( Vector& u) 
 {
     this->u.bind(u);
-    if(q.setSize(u.getSize()))
-        return 1;
+    q.setSize(u.getSize());
     q.setValue(0);
     return 0;
 }
@@ -453,7 +452,7 @@ void
 tnlFiniteVolumeOperatorQ< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
 update( const MeshType& mesh, const RealType& time )
 {
-    CoordinatesType dimensions = mesh.getDimensions();
+    CoordinatesType dimensions = mesh.getMeshDimension();
     CoordinatesType coordinates;
     
     for( coordinates.x()=1; coordinates.x() < dimensions.x()-1; coordinates.x()++ )
@@ -480,76 +479,76 @@ boundaryDerivative(
    const IndexType& dy,
    const IndexType& dz ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();
    const IndexType& cellIndex = entity.getIndex();    
     if ( ( AxeX == 1 ) && ( AxeY == 0 ) && ( AxeZ == 0 ) )
     {
         if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] );
         if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ cellIndex ] - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ] );
         if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,1,0 >() ] );
         if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,-1,0 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,-1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,-1,0 >() ] - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,-1,0 >() ] );
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,0,1 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,0,1 >() ] );
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
-            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,0,-1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,0,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,0,-1 >() ] - u[ neighborEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,0,-1 >() ] );
     }
     if ( ( AxeX == 0 ) && ( AxeY == 1 ) && ( AxeZ == 0 ) )
     {
         if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] );
         if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ cellIndex ] - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] );
         if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 1,-1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 1,-1,0 >() ] );
         if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< -1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,-1,0 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< -1,1,0 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,-1,0 >() ] );
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 0,-1,1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 0,-1,1 >() ] );
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
-            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 0,1,-1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 0,-1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 0,1,-1 >() ] - u[ neighborEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 0,-1,-1 >() ] );
     }
     if ( ( AxeX == 0 ) && ( AxeY == 0 ) && ( AxeZ == 1 ) )
     {
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] );
         if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ cellIndex ] - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] );
         if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 1,0,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 1,0,-1 >() ] );
         if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< -1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< -1,0,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< -1,0,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< -1,0,-1 >() ] );
         if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 0,1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 0,1,-1 >() ] );
         if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
-            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
-                   u[ neighbourEntities.template getEntityIndex< 0,-1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
-                   u[ neighbourEntities.template getEntityIndex< 0,-1,-1 >() ] );
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighborEntities.template getEntityIndex< 0,-1,1 >() ] - u[ neighborEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighborEntities.template getEntityIndex< 0,-1,-1 >() ] );
     }
     return 0.0;
 }
@@ -571,16 +570,16 @@ operator()(
    const IndexType& dy,
    const IndexType& dz ) const
 {
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const IndexType& cellIndex = entity.getIndex();     
     if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 0 ) )
-        return ::sqrt( this->eps + ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] ) * 
-                ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] )
-                * mesh.template getSpaceStepsProducts< 0, -1, 0 >() * mesh.template getSpaceStepsProducts< 0, -1, 0 >() + ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) 
-                * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0, 0 >() * mesh.template getSpaceStepsProducts< -1, 0, 0 >()
-                + ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) 
-                * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, 0, -1 >() * mesh.template getSpaceStepsProducts< 0, 0, -1 >() );
+        return ::sqrt( this->eps + ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] ) * 
+                ( u[ neighborEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] )
+                * mesh.template getSpaceStepsProducts< 0, -1, 0 >() * mesh.template getSpaceStepsProducts< 0, -1, 0 >() + ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighborEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0, 0 >() * mesh.template getSpaceStepsProducts< -1, 0, 0 >()
+                + ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighborEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, 0, -1 >() * mesh.template getSpaceStepsProducts< 0, 0, -1 >() );
     if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
         return ::sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 1, 0, 0 ) * 
                this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 1, 0, 0 ) + 
diff --git a/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ.h b/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ.h
index 29b2ac29091f8490adba7dc91c9b6075aea026b3..a96d22f5134029fb9686150713696da47ff05bfc 100644
--- a/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ.h
+++ b/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ.h
@@ -10,8 +10,6 @@
 
 #pragma once
 
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Meshes/Grid.h>
 
 namespace TNL {
@@ -19,7 +17,7 @@ namespace Operators {
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType > 
+          typename Index = typename Mesh::GlobalIndexType > 
 class tnlOneSideDiffOperatorQ
 {
 };
diff --git a/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h b/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h
index 483680f5a174b11c917fa34b22bc8fdbc47cb788..21f5e44f08ec29fe365de11cfcbb5fb898f9af26 100644
--- a/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h
+++ b/src/TNL/Operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h
@@ -58,9 +58,9 @@ operator()( const MeshFunction& u,
             const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
-   const RealType& u_x = ( u[ neighbourEntities.template getEntityIndex< 1 >() ] - u[ cellIndex ] ) *
+   const RealType& u_x = ( u[ neighborEntities.template getEntityIndex< 1 >() ] - u[ cellIndex ] ) *
                          mesh.template getSpaceStepsProducts< -1 >();
    return ::sqrt( this->epsSquare + u_x * u_x );          
 }
@@ -79,12 +79,12 @@ getValueStriped( const MeshFunction& u,
                  const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const RealType& u_c = u[ cellIndex ];
-   const RealType& u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1 >() ] - u_c ) * 
+   const RealType& u_x_f = ( u[ neighborEntities.template getEntityIndex< 1 >() ] - u_c ) * 
                            mesh.template getSpaceStepsProducts< -1 >();
-   const RealType& u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * 
+   const RealType& u_x_b = ( u_c - u[ neighborEntities.template getEntityIndex< -1 >() ] ) * 
                            mesh.template getSpaceStepsProducts< -1 >();   
    return ::sqrt( this->epsSquare + 0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b ) );
 }
@@ -134,12 +134,12 @@ operator()( const MeshFunction& u,
             const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const RealType& u_c = u[ cellIndex ];
-   const RealType u_x = ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
+   const RealType u_x = ( u[ neighborEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
                          mesh.template getSpaceStepsProducts< -1, 0 >();
-   const RealType u_y = ( u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
+   const RealType u_y = ( u[ neighborEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
                          mesh.template getSpaceStepsProducts< 0, -1 >();
    return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y ); 
 }
@@ -158,16 +158,16 @@ getValueStriped( const MeshFunction& u,
                  const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const RealType& u_c = u[ cellIndex ];
-   const RealType u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
+   const RealType u_x_f = ( u[ neighborEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
                           mesh.template getSpaceStepsProducts< -1, 0 >();
-   const RealType u_y_f = ( u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
+   const RealType u_y_f = ( u[ neighborEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
                           mesh.template getSpaceStepsProducts< 0, -1 >();
-   const RealType u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) *
+   const RealType u_x_b = ( u_c - u[ neighborEntities.template getEntityIndex< -1, 0 >() ] ) *
                           mesh.template getSpaceStepsProducts< -1, 0 >();
-   const RealType u_y_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) *
+   const RealType u_y_b = ( u_c - u[ neighborEntities.template getEntityIndex< 0, -1 >() ] ) *
                           mesh.template getSpaceStepsProducts< 0, -1 >();
    
    return ::sqrt( this->epsSquare + 
@@ -219,15 +219,15 @@ operator()( const MeshFunction& u,
             const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const RealType& u_c =u[ cellIndex ];
    
-   const RealType u_x = ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
+   const RealType u_x = ( u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
                          mesh.template getSpaceStepsProducts< -1, 0, 0 >();
-   const RealType u_y = ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
+   const RealType u_y = ( u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
                          mesh.template getSpaceStepsProducts< 0, -1, 0 >();
-   const RealType u_z = ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
+   const RealType u_z = ( u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
                          mesh.template getSpaceStepsProducts< 0, 0, -1 >();
    return ::sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z ); 
 }
@@ -246,21 +246,21 @@ getValueStriped( const MeshFunction& u,
                  const Real& time ) const
 {
    const IndexType& cellIndex = entity.getIndex();
-   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities();      
    const typename MeshEntity::MeshType& mesh = entity.getMesh();
    const RealType& u_c = u[ cellIndex ];
    
-   const RealType u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
+   const RealType u_x_f = ( u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
                           mesh.template getSpaceStepsProducts< -1, 0, 0 >();
-   const RealType u_y_f = ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
+   const RealType u_y_f = ( u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
                           mesh.template getSpaceStepsProducts< 0, -1, 0 >();
-   const RealType u_z_f = ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
+   const RealType u_z_f = ( u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
                           mesh.template getSpaceStepsProducts< 0, 0, -1 >();   
-   const RealType u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) *
+   const RealType u_x_b = ( u_c - u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ] ) *
                           mesh.template getSpaceStepsProducts< -1, 0, 0 >();
-   const RealType u_y_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) *
+   const RealType u_y_b = ( u_c - u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ] ) *
                           mesh.template getSpaceStepsProducts< 0, -1, 0 >();
-   const RealType u_z_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) *
+   const RealType u_z_b = ( u_c - u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ] ) *
                           mesh.template getSpaceStepsProducts< 0, 0, -1 >();
    
    return ::sqrt( this->epsSquare + 
diff --git a/src/TNL/Operators/operator-curvature/CMakeLists.txt b/src/TNL/Operators/operator-curvature/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Operators/operator-curvature/ExactOperatorCurvature.h b/src/TNL/Operators/operator-curvature/ExactOperatorCurvature.h
index 68cf12eda4ade12447205891675ec6a86b314b6c..33a20e255ce950bfa9714504185c1f236ad4abed 100644
--- a/src/TNL/Operators/operator-curvature/ExactOperatorCurvature.h
+++ b/src/TNL/Operators/operator-curvature/ExactOperatorCurvature.h
@@ -18,7 +18,7 @@
 namespace TNL {
 namespace Operators {   
 
-template< typename ExactOperatorQ, int Dimensions >
+template< typename ExactOperatorQ, int Dimension >
 class ExactOperatorCurvature
 {};
 
@@ -27,20 +27,14 @@ class ExactOperatorCurvature< OperatorQ, 1 >
 {
    public:
 
-      enum { Dimensions = 1 };
+      enum { Dimension = 1 };
 
       static String getType();
 
-#ifdef HAVE_NOT_CXX11      
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
-#else   
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
-#endif
-#ifdef HAVE_CUDA
-      __device__ __host__
-#endif
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Point, typename Real = typename Point::RealType >
+      __cuda_callable__
       static Real getValue( const Function& function,
-                            const Vertex& v,
+                            const Point& v,
                             const Real& time = 0.0, const Real& eps = 1.0 );
       
 };
@@ -50,20 +44,14 @@ class ExactOperatorCurvature< ExactOperatorQ, 2 >
 {
    public:
 
-      enum { Dimensions = 2 };
+      enum { Dimension = 2 };
 
       static String getType();
          
-#ifdef HAVE_NOT_CXX11      
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
-#else   
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
-#endif
-#ifdef HAVE_CUDA
-      __device__ __host__
-#endif      
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Point, typename Real = typename Point::RealType >
+      __cuda_callable__
       static Real getValue( const Function& function,
-                            const Vertex& v,
+                            const Point& v,
                             const Real& time = 0.0, const Real& eps = 1.0 );
 };
 
@@ -72,28 +60,22 @@ class ExactOperatorCurvature< ExactOperatorQ, 3 >
 {
    public:
 
-      enum { Dimensions = 3 };
+      enum { Dimension = 3 };
 
       static String getType();
    
-#ifdef HAVE_NOT_CXX11      
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
-#else   
-      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
-#endif
-#ifdef HAVE_CUDA
-      __device__ __host__
-#endif
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Point, typename Real = typename Point::RealType >
+      __cuda_callable__
       static Real getValue( const Function& function,
-                            const Vertex& v,
+                            const Point& v,
                             const Real& time = 0.0, const Real& eps = 1.0 )
       {
          return 0;
       }
 };
 
-template< typename ExactOperatorQ, int Dimensions >
-class tnlFunctionType< ExactOperatorCurvature< ExactOperatorQ, Dimensions > >
+template< typename ExactOperatorQ, int Dimension >
+class tnlFunctionType< ExactOperatorCurvature< ExactOperatorQ, Dimension > >
 {
    public:
       enum { Type = tnlSpaceDomain };
diff --git a/src/TNL/Operators/operator-curvature/ExactOperatorCurvature_impl.h b/src/TNL/Operators/operator-curvature/ExactOperatorCurvature_impl.h
index ef268feb31381bc4fe5d534eda2c87c6a2f9dde9..f07610f4b1d777b1a99a05405e3fa44a50eb5bd1 100644
--- a/src/TNL/Operators/operator-curvature/ExactOperatorCurvature_impl.h
+++ b/src/TNL/Operators/operator-curvature/ExactOperatorCurvature_impl.h
@@ -24,21 +24,21 @@ getType()
 }
 
 template< typename OperatorQ >
-template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Vertex, typename Real >
+template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Point, typename Real >
 #ifdef HAVE_CUDA
    __device__ __host__
 #endif
 Real
 tnlExactOperatorQ< 1 >::
 getValue( const Function& function,
-          const Vertex& v,
+          const Point& v,
           const Real& time, const Real& eps )
 {
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
         return 0.0;
    if (XDiffOrder == 0)
-        return function.template getValue< 2, 0, 0, Vertex >( v, time )/ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) -
-               ( function.template getValue< 1, 0, 0, Vertex >( v, time ) * ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) )
+        return function.template getValue< 2, 0, 0, Point >( v, time )/ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) -
+               ( function.template getValue< 1, 0, 0, Point >( v, time ) * ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) )
                 / ( ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) * ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) );
    return 0;
 }
@@ -51,22 +51,22 @@ getType()
    return "ExactOperatorCurvature< " + ExactOperatorQ::getType() + ",2 >";
 }
 
-template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Vertex, typename Real >
+template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Point, typename Real >
 #ifdef HAVE_CUDA
    __device__ __host__
 #endif
 Real
 tnlExactOperatorQ< 2 >::
 getValue( const Function& function,
-          const Vertex& v,
+          const Point& v,
           const Real& time, const Real& eps )
 {
    if( ZDiffOrder != 0 )
         return 0.0;
    if (XDiffOrder == 0 && YDiffOrder == 0 )
-        return ( function.template getValue< 2, 0, 0, Vertex >( v, time ) * function.template getValue< 0, 2, 0, Vertex >( v, time ) )
-               /ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) - ( function.template getValue< 1, 0, 0, Vertex >( v, time ) *
-               ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) + function.template getValue< 0, 1, 0, Vertex >( v, time ) *
+        return ( function.template getValue< 2, 0, 0, Point >( v, time ) * function.template getValue< 0, 2, 0, Point >( v, time ) )
+               /ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) - ( function.template getValue< 1, 0, 0, Point >( v, time ) *
+               ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) + function.template getValue< 0, 1, 0, Point >( v, time ) *
                ExactOperatorQ::template getValue< 0, 1, 0 >( function, v, time, eps ) )
                 / ( ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) * ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) );
    return 0;
diff --git a/src/TNL/ParallelFor.h b/src/TNL/ParallelFor.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1e81ca97bf66576875aa1d0dcb34ecc0298d5df
--- /dev/null
+++ b/src/TNL/ParallelFor.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+                          ParallelFor.h  -  description
+                             -------------------
+    begin                : Mar 10, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Devices/Host.h>
+#include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/CudaDeviceInfo.h>
+
+/*
+ * The implementation of ParallelFor is not meant to provide maximum performance
+ * at every cost, but maximum flexibility for operating with data stored on the
+ * device.
+ *
+ * The grid-stride loop for CUDA has been inspired by Nvidia's blog post:
+ * https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
+ *
+ * Implemented by: Jakub Klinkovsky
+ */
+
+namespace TNL {
+
+template< typename Device = Devices::Host >
+struct ParallelFor
+{
+   template< typename Index,
+             typename Function,
+             typename... FunctionArgs >
+   static void exec( Index start, Index end, Function f, FunctionArgs... args )
+   {
+#ifdef HAVE_OPENMP
+      #pragma omp parallel for if( TNL::Devices::Host::isOMPEnabled() && end - start > 512 )
+#endif
+      for( Index i = start; i < end; i++ )
+         f( i, args... );
+   }
+};
+
+#ifdef HAVE_CUDA
+template< typename Index,
+          typename Function,
+          typename... FunctionArgs >
+__global__ void
+ParallelForKernel( Index start, Index end, Function f, FunctionArgs... args )
+{
+   for( Index i = start + blockIdx.x * blockDim.x + threadIdx.x;
+        i < end;
+        i += blockDim.x * gridDim.x )
+   {
+      f( i, args... );
+   }
+}
+#endif
+
+template<>
+struct ParallelFor< Devices::Cuda >
+{
+   template< typename Index,
+             typename Function,
+             typename... FunctionArgs >
+   static void exec( Index start, Index end, Function f, FunctionArgs... args )
+   {
+#ifdef HAVE_CUDA
+      if( end > start ) {
+         dim3 blockSize( 256 );
+         dim3 gridSize;
+         const int desGridSize = 32 * Devices::CudaDeviceInfo::getCudaMultiprocessors( Devices::CudaDeviceInfo::getActiveDevice() );
+         gridSize.x = min( desGridSize, Devices::Cuda::getNumberOfBlocks( end - start, blockSize.x ) );
+
+         Devices::Cuda::synchronizeDevice();
+         ParallelForKernel<<< gridSize, blockSize >>>( start, end, f, args... );
+      }
+#endif
+   }
+};
+
+} // namespace TNL
diff --git a/src/TNL/Problems/CMakeLists.txt b/src/TNL/Problems/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Problems/HeatEquationEocRhs.h b/src/TNL/Problems/HeatEquationEocRhs.h
index 4243cebb10b806cf40c69146ab0362d7a0753677..c4d8e8a10f0829e60723ec2299ebbf0f027128d5 100644
--- a/src/TNL/Problems/HeatEquationEocRhs.h
+++ b/src/TNL/Problems/HeatEquationEocRhs.h
@@ -24,14 +24,14 @@ namespace Problems {
 template< typename ExactOperator,
           typename TestFunction >
 class HeatEquationEocRhs
- : public Functions::Domain< TestFunction::Dimensions, Functions::SpaceDomain >
+ : public Functions::Domain< TestFunction::Dimension, Functions::SpaceDomain >
 {
    public:
 
       typedef ExactOperator ExactOperatorType;
       typedef TestFunction TestFunctionType;
       typedef typename TestFunction::RealType RealType;
-      typedef typename TestFunction::VertexType VertexType;
+      typedef typename TestFunction::PointType PointType;
 
       bool setup( const Config::ParameterContainer& parameters,
                   const String& prefix = "" )
@@ -42,7 +42,7 @@ class HeatEquationEocRhs
       }
 
       __cuda_callable__
-      RealType operator()( const VertexType& vertex,
+      RealType operator()( const PointType& vertex,
                          const RealType& time = 0.0 ) const
       {
          return testFunction.getTimeDerivative( vertex, time )
diff --git a/src/TNL/Problems/HeatEquationProblem.h b/src/TNL/Problems/HeatEquationProblem.h
index 94bc122fdbb74b4b1cdc7ae8d1d1abac33f293ca..cb01045e6cd00aec1d91f19357cc555144f4848e 100644
--- a/src/TNL/Problems/HeatEquationProblem.h
+++ b/src/TNL/Problems/HeatEquationProblem.h
@@ -22,6 +22,8 @@
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Timer.h>
 #include <TNL/Solvers/PDE/ExplicitUpdater.h>
+#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
+#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
 
 namespace TNL {
 namespace Problems {
@@ -32,9 +34,9 @@ template< typename Mesh,
           typename DifferentialOperator = Operators::LinearDiffusion< Mesh,
                                                               typename BoundaryCondition::RealType > >
 class HeatEquationProblem : public PDEProblem< Mesh,
-                                                     typename DifferentialOperator::RealType,
-                                                     typename Mesh::DeviceType,
-                                                     typename DifferentialOperator::IndexType  >
+                                               typename DifferentialOperator::RealType,
+                                               typename Mesh::DeviceType,
+                                               typename DifferentialOperator::IndexType  >
 {
    public:
 
@@ -44,7 +46,7 @@ class HeatEquationProblem : public PDEProblem< Mesh,
       typedef Functions::MeshFunction< Mesh > MeshFunctionType;
       typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer;
       typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;
-      typedef Matrices::CSR< RealType, DeviceType, IndexType > MatrixType;
+      typedef Matrices::SlicedEllpack< RealType, DeviceType, IndexType > MatrixType;
       typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer;
       typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer;
       typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
@@ -90,12 +92,12 @@ class HeatEquationProblem : public PDEProblem< Mesh,
       void bindDofs( const MeshPointer& meshPointer,
                      const DofVectorPointer& dofs );
 
-      void getExplicitRHS( const RealType& time,
-                           const RealType& tau,
-                           const MeshPointer& meshPointer,
-                           DofVectorPointer& _u,
-                           DofVectorPointer& _fu,
-                           MeshDependentDataPointer& meshDependentData );
+      void getExplicitUpdate( const RealType& time,
+                              const RealType& tau,
+                              const MeshPointer& meshPointer,
+                              DofVectorPointer& _u,
+                              DofVectorPointer& _fu,
+                              MeshDependentDataPointer& meshDependentData );
 
       template< typename MatrixPointer >
       void assemblyLinearSystem( const RealType& time,
@@ -106,10 +108,15 @@ class HeatEquationProblem : public PDEProblem< Mesh,
                                  DofVectorPointer& rightHandSidePointer,
                                  MeshDependentDataPointer& meshDependentData );
 
+      template< typename Matrix >
+      void saveFailedLinearSystem( const Matrix& matrix,
+                                   const DofVectorType& dofs,
+                                   const DofVectorType& rightHandSide ) const;
 
       protected:
          
          MeshFunctionPointer uPointer;
+         MeshFunctionPointer fuPointer;
       
          DifferentialOperatorPointer differentialOperatorPointer;
 
@@ -120,6 +127,14 @@ class HeatEquationProblem : public PDEProblem< Mesh,
          Timer gpuTransferTimer;
          
          Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+         
+         Solvers::PDE::LinearSystemAssembler< Mesh, 
+                                              MeshFunctionType,
+                                              DifferentialOperator,
+                                              BoundaryCondition,
+                                              RightHandSide,
+                                              Solvers::PDE::BackwardTimeDiscretisation,
+                                              DofVectorType > systemAssembler;
 };
 
 } // namespace Problems
diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h
index 38eaba46820fb9d037d71250a811481af605c7dd..39255752baa2c81112a9db5238ef30fc2bec4c90 100644
--- a/src/TNL/Problems/HeatEquationProblem_impl.h
+++ b/src/TNL/Problems/HeatEquationProblem_impl.h
@@ -21,8 +21,6 @@
 #include <TNL/Matrices/MultidiagonalMatrixSetter.h>
 #include <TNL/Logger.h>
 #include <TNL/Solvers/PDE/BoundaryConditionsSetter.h>
-#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
-#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
 
 #include "HeatEquationProblem.h"
 
@@ -69,8 +67,6 @@ bool
 HeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
 writeEpilog( Logger& logger )
 {
-   logger.writeParameter< const char* >( "GPU transfer time:", "" );
-   this->gpuTransferTimer.writeLog( logger, 1 );
    return true;
 }
 
@@ -156,19 +152,17 @@ setupLinearSystem( const MeshPointer& meshPointer,
                    MatrixPointer& matrixPointer )
 {
    const IndexType dofs = this->getDofs( meshPointer );
-   typedef typename MatrixPointer::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   SharedPointer< CompressedRowsLengthsVectorType > rowLengthsPointer;
-   if( ! rowLengthsPointer->setSize( dofs ) )
-      return false;
-   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >(
+   typedef typename MatrixPointer::ObjectType::CompressedRowLengthsVector CompressedRowLengthsVectorType;
+   SharedPointer< CompressedRowLengthsVectorType > rowLengthsPointer;
+   rowLengthsPointer->setSize( dofs );
+   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >(
       meshPointer,
       differentialOperatorPointer,
       boundaryConditionPointer,
       rowLengthsPointer );
    matrixPointer->setDimensions( dofs, dofs );
-   if( ! matrixPointer->setCompressedRowsLengths( *rowLengthsPointer ) )
-      return false;
+   matrixPointer->setCompressedRowLengths( *rowLengthsPointer );
    return true;
    //return MultidiagonalMatrixSetter< Mesh >::setupMatrix( mesh, matrix );
 }
@@ -185,10 +179,10 @@ makeSnapshot( const RealType& time,
               DofVectorPointer& dofs,
               MeshDependentDataPointer& meshDependentData )
 {
-  std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
+   std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
 
    this->bindDofs( meshPointer, dofs );
-   //cout << "dofs = " << dofs << endl;
+
    FileName fileName;
    fileName.setFileNameBase( "u-" );
    fileName.setExtension( "tnl" );
@@ -204,7 +198,7 @@ template< typename Mesh,
           typename DifferentialOperator >
 void
 HeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getExplicitRHS( const RealType& time,
+getExplicitUpdate( const RealType& time,
                 const RealType& tau,
                 const MeshPointer& meshPointer,
                 DofVectorPointer& uDofs,
@@ -221,27 +215,11 @@ getExplicitRHS( const RealType& time,
     */
    
    this->bindDofs( meshPointer, uDofs );
-   MeshFunctionPointer fuPointer( meshPointer, fuDofs );   
-   explicitUpdater.template update< typename Mesh::Cell >(
-      time,
-      meshPointer,
-      this->differentialOperatorPointer,
-      this->boundaryConditionPointer,
-      this->rightHandSidePointer,
-      this->uPointer,
-      fuPointer );
-   //std::cerr << "******************************************************************************************" << std::endl;
-   //std::cerr << "******************************************************************************************" << std::endl;
-   //std::cerr << "******************************************************************************************" << std::endl;
-   /*Solvers::PDE::BoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter;
-   boundaryConditionsSetter.template apply< typename Mesh::Cell >(
-      this->boundaryConditionPointer,
-      time + tau,
-      this->uPointer );*/
-   
-   //uPointer->write( "u.txt", "gnuplot" );
-   //fuPointer->write( "fu.txt", "gnuplot" );
-   //getchar();
+   MeshFunctionPointer fuPointer( meshPointer, fuDofs );
+   this->explicitUpdater.setDifferentialOperator( this->differentialOperatorPointer ),
+   this->explicitUpdater.setBoundaryConditions( this->boundaryConditionPointer ),
+   this->explicitUpdater.setRightHandSide( this->rightHandSidePointer ),
+   this->explicitUpdater.template update< typename Mesh::Cell >( time, tau, meshPointer, this->uPointer, fuPointer );
 }
 
 template< typename Mesh,
@@ -260,48 +238,29 @@ assemblyLinearSystem( const RealType& time,
                       MeshDependentDataPointer& meshDependentData )
 {
    this->bindDofs( meshPointer, dofsPointer );
-   Solvers::PDE::LinearSystemAssembler< Mesh,
-                             MeshFunctionType,
-                             DifferentialOperator,
-                             BoundaryCondition,
-                             RightHandSide,
-                             Solvers::PDE::BackwardTimeDiscretisation,
-                             typename MatrixPointer::ObjectType,
-                             DofVectorType > systemAssembler;
-   systemAssembler.template assembly< typename Mesh::Cell >(
+   this->systemAssembler.setDifferentialOperator( this->differentialOperatorPointer );
+   this->systemAssembler.setBoundaryConditions( this->boundaryConditionPointer );
+   this->systemAssembler.setRightHandSide( this->rightHandSidePointer );
+   this->systemAssembler.template assembly< typename Mesh::Cell, typename MatrixPointer::ObjectType >( 
       time,
       tau,
       meshPointer,
-      this->differentialOperatorPointer,
-      this->boundaryConditionPointer,
-      this->rightHandSidePointer,
       this->uPointer,
       matrixPointer,
       bPointer );
-   /*matrix.print( cout );
-   cout << endl << b << endl;
-   cout << endl << u << endl;
-   abort();*/
-   /*cout << "Matrix multiplication test ..." << std::endl;
-   Vector< RealType, DeviceType, IndexType > y;
-   y.setLike( u );
-   Timer timer;
-   timer.reset();
-   timer.start();
-   for( int i = 0; i < 100; i++ )
-      matrix.vectorProduct( u, y );
-   timer.stop();
-  std::cout << "The time is " << timer.getRealTime();
-  std::cout << "Scalar product test ..." << std::endl;
-   timer.reset();
-   RealType a;
-   timer.start();
-   for( int i = 0; i < 100; i++ )
-      a = y.scalarProduct( u );
-   timer.stop();
-  std::cout << "The time is " << timer.getRealTime();
-  std::cout << std::endl;
-   abort();*/
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+    template< typename Matrix >
+void
+HeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+saveFailedLinearSystem( const Matrix& matrix,
+                        const DofVectorType& dofs,
+                        const DofVectorType& rightHandSide ) const
+{
 }
 
 } // namespace Problems
diff --git a/src/TNL/Problems/MeanCurvatureFlowEocProblem.h b/src/TNL/Problems/MeanCurvatureFlowEocProblem.h
index a756ffea10ecf4c9780ce776024303ca570511ae..057b331bb7a048e9e8f23416e911b9dc443b5743 100644
--- a/src/TNL/Problems/MeanCurvatureFlowEocProblem.h
+++ b/src/TNL/Problems/MeanCurvatureFlowEocProblem.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Problems/MeanCurvatureFlowProblem.h>
diff --git a/src/TNL/Problems/MeanCurvatureFlowEocProblem_impl.h b/src/TNL/Problems/MeanCurvatureFlowEocProblem_impl.h
index 57df68026df292fb74af638babcb222875d1ed89..065e39ac6c18a5a2d103c93ea805dd6e1b51a2b6 100644
--- a/src/TNL/Problems/MeanCurvatureFlowEocProblem_impl.h
+++ b/src/TNL/Problems/MeanCurvatureFlowEocProblem_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 namespace TNL {
diff --git a/src/TNL/Problems/MeanCurvatureFlowEocRhs.h b/src/TNL/Problems/MeanCurvatureFlowEocRhs.h
index cb07a2a13e74fd109a9e9a005e0e5482d19ee52e..8898c8f6bbb00edcfc5cce127e3a3db755302d0b 100644
--- a/src/TNL/Problems/MeanCurvatureFlowEocRhs.h
+++ b/src/TNL/Problems/MeanCurvatureFlowEocRhs.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Functions/Domain.h>
@@ -17,15 +23,15 @@ namespace Problems {
 
 template< typename ExactOperator,
           typename TestFunction,
-          int Dimensions >
-class MeanCurvatureFlowEocRhs : public Domain< Dimensions, SpaceDomain >
+          int Dimension >
+class MeanCurvatureFlowEocRhs : public Domain< Dimension, SpaceDomain >
 {
    public:
 
       typedef ExactOperator ExactOperatorType;
       typedef TestFunction TestFunctionType;
       typedef typename TestFunctionType::RealType RealType;
-      typedef StaticVector< Dimensions, RealType > VertexType;
+      typedef StaticVector< Dimension, RealType > PointType;
 
       bool setup( const Config::ParameterContainer& parameters,
                   const String& prefix = "" )
@@ -35,10 +41,10 @@ class MeanCurvatureFlowEocRhs : public Domain< Dimensions, SpaceDomain >
          return true;
       };
 
-      template< typename Vertex,
+      template< typename Point,
                 typename Real >
       __cuda_callable__
-      Real operator()( const Vertex& vertex,
+      Real operator()( const Point& vertex,
                        const Real& time ) const
       {
          return testFunction.getTimeDerivative( vertex, time )
diff --git a/src/TNL/Problems/MeanCurvatureFlowProblem.h b/src/TNL/Problems/MeanCurvatureFlowProblem.h
index 02ac91c9b7f54fd5cce6d39a334b50a2904b3f41..a06049647dcc0ef45ef7540fb3e9fd1ae39f479c 100644
--- a/src/TNL/Problems/MeanCurvatureFlowProblem.h
+++ b/src/TNL/Problems/MeanCurvatureFlowProblem.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/Operators/diffusion/OneSidedMeanCurvature.h>
@@ -25,7 +31,7 @@ template< typename Mesh,
           typename DifferentialOperator =
             OneSidedMeanCurvature< Mesh,
                                       typename Mesh::RealType,
-                                      typename Mesh::IndexType,
+                                      typename Mesh::GlobalIndexType,
                                       false > >
 class MeanCurvatureFlowProblem : public PDEProblem< Mesh,
                                                      typename DifferentialOperator::RealType,
@@ -75,7 +81,7 @@ class MeanCurvatureFlowProblem : public PDEProblem< Mesh,
       void bindDofs( const MeshType& mesh,
                      DofVectorType& dofs );
 
-      void getExplicitRHS( const RealType& time,
+      void getExplicitUpdate( const RealType& time,
                            const RealType& tau,
                            const MeshType& mesh,
                            DofVectorType& _u,
@@ -91,6 +97,10 @@ class MeanCurvatureFlowProblem : public PDEProblem< Mesh,
                                  DofVectorType& rightHandSide,
                                  MeshDependentDataPointer& meshDependentData );
 
+      template< typename Matrix >
+      void saveFailedLinearSystem( const Matrix& matrix,
+                                   const DofVectorType& dofs,
+                                   const DofVectorType& rightHandSide ) const;
 
       protected:
 
diff --git a/src/TNL/Problems/MeanCurvatureFlowProblem_impl.h b/src/TNL/Problems/MeanCurvatureFlowProblem_impl.h
index 6a52f2e950409735912ad94dc884dfdba15ad947..4dcba17fcd9ca6f78ce16aba0df8b6128ea8f3f0 100644
--- a/src/TNL/Problems/MeanCurvatureFlowProblem_impl.h
+++ b/src/TNL/Problems/MeanCurvatureFlowProblem_impl.h
@@ -8,6 +8,12 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+/***
+ * Authors:
+ * Oberhuber Tomas, tomas.oberhuber@fjfi.cvut.cz
+ * Szekely Ondrej, ondra.szekely@gmail.com
+ */
+
 #pragma once
 
 #include <TNL/FileName.h>
@@ -132,20 +138,18 @@ setupLinearSystem( const MeshType& mesh,
                    Matrix& matrix )
 {
    const IndexType dofs = this->getDofs( mesh );
-   typedef typename MatrixType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   CompressedRowsLengthsVectorType rowLengths;
-   if( ! rowLengths.setSize( dofs ) )
-      return false;
-   MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >(
+   typedef typename MatrixType::CompressedRowLengthsVector CompressedRowLengthsVectorType;
+   CompressedRowLengthsVectorType rowLengths;
+   rowLengths.setSize( dofs );
+   MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >(
       mesh,
       differentialOperator,
       boundaryCondition,
       rowLengths
    );
    matrix.setDimensions( dofs, dofs );
-   if( ! matrix.setCompressedRowsLengths( rowLengths ) )
-      return false;
+   matrix.setCompressedRowLengths( rowLengths );
    return true;
 }
 
@@ -178,7 +182,7 @@ template< typename Mesh,
           typename DifferentialOperator >
 void
 MeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getExplicitRHS( const RealType& time,
+getExplicitUpdate( const RealType& time,
                 const RealType& tau,
                 const MeshType& mesh,
                 DofVectorType& inDofs,
@@ -202,21 +206,12 @@ getExplicitRHS( const RealType& time,
    MeshFunctionType fu( mesh, outDofs );
    //differentialOperator.nonlinearDiffusionOperator.operatorQ.update( mesh, time );
    ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
-   explicitUpdater.template update< typename Mesh::Cell >(
-      time,
-      mesh,
-      this->differentialOperator,
-      this->boundaryCondition,
-      this->rightHandSide,
-      u,
-      fu );
+   explicitUpdater.setDifferentialOperator( this->differentialOperatorPointer );
+   explicitUpdater.setBoundaryConditions( this->boundaryConditionPointer );
+   explicitUpdater.setRightHandSide( this->rightHandSidePointer );
+   
+   explicitUpdater.template update< typename Mesh::Cell >( time, tau, mesh, u, fu );
  
-   BoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter;
-   boundaryConditionsSetter.template apply< typename Mesh::Cell >(
-      this->boundaryCondition,
-      time,
-      u );
-
    /*cout << "u = " << u << std::endl;
   std::cout << "fu = " << fu << std::endl;
    u.save( "u.tnl" );
@@ -265,5 +260,18 @@ assemblyLinearSystem( const RealType& time,
    //abort();*/
 }
 
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+    template< typename Matrix >
+void
+MeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+saveFailedLinearSystem( const Matrix& matrix,
+                        const DofVectorType& dofs,
+                        const DofVectorType& rightHandSide ) const
+{
+}
+
 } // namespace Problems
 } // namespace TNL
diff --git a/src/TNL/Problems/PDEProblem.h b/src/TNL/Problems/PDEProblem.h
index 612e325e3771ec2560c955fe3ff64a98e19f3920..2da2f9981f1bc12673096d278c20a4b3b1b7eedc 100644
--- a/src/TNL/Problems/PDEProblem.h
+++ b/src/TNL/Problems/PDEProblem.h
@@ -12,7 +12,7 @@
 
 #include <TNL/Problems/Problem.h>
 #include <TNL/SharedPointer.h>
-#include <TNL/Matrices/CSR.h>
+#include <TNL/Matrices/SlicedEllpack.h>
 
 namespace TNL {
 namespace Problems {
@@ -20,7 +20,7 @@ namespace Problems {
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
           typename Device = typename Mesh::DeviceType,
-          typename Index = typename Mesh::IndexType >
+          typename Index = typename Mesh::GlobalIndexType >
 class PDEProblem : public Problem< Real, Device, Index >
 {
    public:
@@ -34,7 +34,7 @@ class PDEProblem : public Problem< Real, Device, Index >
       typedef SharedPointer< MeshType, DeviceType > MeshPointer;
       typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType;
       typedef SharedPointer< DofVectorType, DeviceType > DofVectorPointer;
-      typedef Matrices::CSR< RealType, DeviceType, IndexType > MatrixType;
+      typedef Matrices::SlicedEllpack< RealType, DeviceType, IndexType > MatrixType;
       typedef Containers::Vector< RealType, DeviceType, IndexType > MeshDependentDataType;
       typedef SharedPointer< MeshDependentDataType, DeviceType > MeshDependentDataPointer;
 
diff --git a/src/TNL/Problems/cfd/CMakeLists.txt b/src/TNL/Problems/cfd/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Problems/cfd/navier-stokes/CMakeLists.txt b/src/TNL/Problems/cfd/navier-stokes/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver.h b/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver.h
index 634b1615e21b41f490551ee706fe355225e5730e..cf74d48ffe03724360e3904e6d974815beb75697 100644
--- a/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver.h
+++ b/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver.h
@@ -104,7 +104,7 @@ class NavierStokesSolver
                                   const Vector& e );
 
    template< typename SolverVectorType >
-   void getExplicitRhs( const RealType& time,
+   void getExplicitUpdate( const RealType& time,
                         const RealType& tau,
                         SolverVectorType& u,
                         SolverVectorType& fu );
diff --git a/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver_impl.h b/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver_impl.h
index e96231f525ec7d4a8c6d4e801dca997388d7a02b..229ff4667b4e6d0c84e1ba27dd5464f40dd94b7f 100644
--- a/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver_impl.h
+++ b/src/TNL/Problems/cfd/navier-stokes/NavierStokesSolver_impl.h
@@ -340,15 +340,15 @@ template< typename AdvectionScheme,
    template< typename SolverVectorType >
 void NavierStokesSolver< AdvectionScheme,
                       DiffusionScheme,
-                      BoundaryConditions >::getExplicitRhs( const RealType& time,
+                      BoundaryConditions >::getExplicitUpdate( const RealType& time,
                                                             const RealType& tau,
                                                             SolverVectorType& u,
                                                             SolverVectorType& fu )
 {
-   Assert( this->advection, );
-   Assert( this->u1Viscosity, );
-   Assert( this->u2Viscosity, );
-   Assert( this->boundaryConditions, );
+   TNL_ASSERT_TRUE( this->advection, "advection scheme was not set" );
+   TNL_ASSERT_TRUE( this->u1Viscosity, "diffusion scheme was not set" );
+   TNL_ASSERT_TRUE( this->u2Viscosity, "diffusion scheme was not set" );
+   TNL_ASSERT_TRUE( this->boundaryConditions, "boundary conditions were not set" );
 
    SharedVector< RealType, DeviceType, IndexType > dofs_rho, dofs_rho_u1, dofs_rho_u2, dofs_e,
                                                       rho_t, rho_u1_t, rho_u2_t, e_t;
@@ -454,7 +454,7 @@ void NavierStokesSolver< AdvectionScheme,
            continue;
         }
 
-        this->advection->getExplicitRhs( c,
+        this->advection->getExplicitUpdate( c,
                                          rho_t[ c ],
                                          rho_u1_t[ c ],
                                          rho_u2_t[ c ],
diff --git a/src/TNL/SharedPointer.h b/src/TNL/SharedPointer.h
index f9120f023a9a2c1e01116080386d40228f207451..c9e71427518d373f26aec6ff57e386f5809d7365 100644
--- a/src/TNL/SharedPointer.h
+++ b/src/TNL/SharedPointer.h
@@ -1,29 +1,26 @@
-/***************************************************************************
- *                                                                         *
- *   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.                                   *
- *                                                                         *
- ***************************************************************************/
-
 /***************************************************************************
                           SharedPointer.h  -  description
                              -------------------
     begin                : May 6, 2016
-    copyright            : (C) 2016 by Tomas Oberhuber
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber, Jakub Klinkovsky
+
 #pragma once
 
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/MIC.h>
 #include <TNL/SmartPointer.h>
 
 #include <cstring>
 
 
+
 //#define TNL_DEBUG_SHARED_POINTERS
 
 #ifdef TNL_DEBUG_SHARED_POINTERS
@@ -47,13 +44,8 @@
 
 namespace TNL {
 
-/***
- * Use the lazy mode if you do not want to call the object constructor in the
- * shared pointer constructor. You may call it later via the method recreate.
- */
 template< typename Object,
-          typename Device = typename Object::DeviceType,
-          bool lazy = false >
+          typename Device = typename Object::DeviceType >
 class SharedPointer
 {
    static_assert( ! std::is_same< Device, void >::value, "The device cannot be void. You need to specify the device explicitly in your code." );
@@ -62,8 +54,8 @@ class SharedPointer
 /****
  * Specialization for Devices::Host
  */
-template< typename Object, bool lazy >
-class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
+template< typename Object >
+class SharedPointer< Object, Devices::Host > : public SmartPointer
 {
    private:
       // Convenient template alias for controlling the selection of copy- and
@@ -75,14 +67,14 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
                                       std::is_same< typename std::remove_cv< Object >::type, Object_ >::value >;
 
       // friend class will be needed for templated assignment operators
-      template< typename Object_, typename Device_, bool lazy_ >
+      template< typename Object_, typename Device_ >
       friend class SharedPointer;
 
    public:
 
       typedef Object ObjectType;
       typedef Devices::Host DeviceType;
-      typedef SharedPointer< Object, Devices::Host, lazy > ThisType;
+      typedef SharedPointer< Object, Devices::Host > ThisType;
 
       template< typename... Args >
       explicit  SharedPointer( Args... args )
@@ -91,8 +83,7 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
 #ifdef TNL_DEBUG_SHARED_POINTERS
          std::cerr << "Creating shared pointer to " << demangle(typeid(ObjectType).name()) << std::endl;
 #endif
-         if( ! lazy )
-            this->allocate( args... );
+         this->allocate( args... );
       }
 
       // this is needed only to avoid the default compiler-generated constructor
@@ -103,9 +94,9 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
       }
 
       // conditional constructor for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      SharedPointer( const SharedPointer< Object_, DeviceType, lazy_ >& pointer )
+      SharedPointer( const SharedPointer< Object_, DeviceType >& pointer )
       : pd( (PointerData*) pointer.pd )
       {
          this->pd->counter += 1;
@@ -119,9 +110,9 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
       }
 
       // conditional constructor for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      SharedPointer( SharedPointer< Object_, DeviceType, lazy_ >&& pointer )
+      SharedPointer( SharedPointer< Object_, DeviceType >&& pointer )
       : pd( (PointerData*) pointer.pd )
       {
          pointer.pd = nullptr;
@@ -172,11 +163,18 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
          return this->pd->data;
       }
 
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pd;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pd;
+      }
+
       template< typename Device = Devices::Host >
       __cuda_callable__
       const Object& getData() const
@@ -201,9 +199,9 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
       }
 
       // conditional operator for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      const ThisType& operator=( const SharedPointer< Object_, DeviceType, lazy_ >& ptr )
+      const ThisType& operator=( const SharedPointer< Object_, DeviceType >& ptr )
       {
          this->free();
          this->pd = (PointerData*) ptr.pd;
@@ -221,9 +219,9 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
       }
 
       // conditional operator for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      const ThisType& operator=( SharedPointer< Object_, DeviceType, lazy_ >&& ptr )
+      const ThisType& operator=( SharedPointer< Object_, DeviceType >&& ptr )
       {
          this->free();
          this->pd = (PointerData*) ptr.pd;
@@ -235,6 +233,11 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
       {
          return true;
       }
+      
+      void clear()
+      {
+         this->free();
+      }
 
       ~SharedPointer()
       {
@@ -282,8 +285,8 @@ class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
 /****
  * Specialization for CUDA
  */
-template< typename Object, bool lazy >
-class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
+template< typename Object >
+class SharedPointer< Object, Devices::Cuda > : public SmartPointer
 {
    private:
       // Convenient template alias for controlling the selection of copy- and
@@ -295,22 +298,21 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
                                       std::is_same< typename std::remove_cv< Object >::type, Object_ >::value >;
 
       // friend class will be needed for templated assignment operators
-      template< typename Object_, typename Device_, bool lazy_ >
+      template< typename Object_, typename Device_ >
       friend class SharedPointer;
 
    public:
 
       typedef Object ObjectType;
       typedef Devices::Cuda DeviceType;
-      typedef SharedPointer< Object, Devices::Cuda, lazy > ThisType;
+      typedef SharedPointer< Object, Devices::Cuda > ThisType;
 
       template< typename... Args >
       explicit  SharedPointer( Args... args )
       : pd( nullptr ),
         cuda_pointer( nullptr )
       {
-         if( ! lazy )
-            this->allocate( args... );
+         this->allocate( args... );
       }
 
       // this is needed only to avoid the default compiler-generated constructor
@@ -322,9 +324,9 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       }
 
       // conditional constructor for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      SharedPointer( const SharedPointer< Object_, DeviceType, lazy_ >& pointer )
+      SharedPointer( const SharedPointer< Object_, DeviceType >& pointer )
       : pd( (PointerData*) pointer.pd ),
         cuda_pointer( pointer.cuda_pointer )
       {
@@ -341,9 +343,9 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       }
 
       // conditional constructor for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      SharedPointer( SharedPointer< Object_, DeviceType, lazy_ >&& pointer )
+      SharedPointer( SharedPointer< Object_, DeviceType >&& pointer )
       : pd( (PointerData*) pointer.pd ),
         cuda_pointer( pointer.cuda_pointer )
       {
@@ -402,18 +404,25 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
          return this->pd->data;
       }
 
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pd;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pd;
+      }
+
       template< typename Device = Devices::Host >
       __cuda_callable__
       const Object& getData() const
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
             return this->pd->data;
          if( std::is_same< Device, Devices::Cuda >::value )
@@ -425,8 +434,8 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       Object& modifyData()
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
          {
             this->pd->maybe_modified = true;
@@ -450,9 +459,9 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       }
 
       // conditional operator for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      const ThisType& operator=( const SharedPointer< Object_, DeviceType, lazy_ >& ptr )
+      const ThisType& operator=( const SharedPointer< Object_, DeviceType >& ptr )
       {
          this->free();
          this->pd = (PointerData*) ptr.pd;
@@ -479,9 +488,9 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       }
 
       // conditional operator for non-const -> const data
-      template< typename Object_, bool lazy_,
+      template< typename Object_,
                 typename = typename Enabler< Object_ >::type >
-      const ThisType& operator=( SharedPointer< Object_, DeviceType, lazy_ >&& ptr )
+      const ThisType& operator=( SharedPointer< Object_, DeviceType >&& ptr )
       {
          this->free();
          this->pd = (PointerData*) ptr.pd;
@@ -505,9 +514,9 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
             std::cerr << "Synchronizing shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(Object).name()) << std::endl;
             std::cerr << "   ( " << sizeof( Object ) << " bytes, CUDA adress " << this->cuda_pointer << " )" << std::endl;
 #endif
-            Assert( this->cuda_pointer, );
+            TNL_ASSERT( this->cuda_pointer, );
             cudaMemcpy( (void*) this->cuda_pointer, (void*) &this->pd->data, sizeof( Object ), cudaMemcpyHostToDevice );
-            if( ! checkCudaDevice ) {
+            if( ! TNL_CHECK_CUDA_DEVICE ) {
                return false;
             }
             this->set_last_sync_state();
@@ -518,6 +527,11 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
          return false;
 #endif
       }
+      
+      void clear()
+      {
+         this->free();
+      }      
 
       ~SharedPointer()
       {
@@ -546,12 +560,8 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       bool allocate( Args... args )
       {
          this->pd = new PointerData( args... );
-         if( ! this->pd )
-            return false;
          // pass to device
          this->cuda_pointer = Devices::Cuda::passToDevice( this->pd->data );
-         if( ! this->cuda_pointer )
-            return false;
          // set last-sync state
          this->set_last_sync_state();
 #ifdef TNL_DEBUG_SHARED_POINTERS
@@ -563,14 +573,14 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
 
       void set_last_sync_state()
       {
-         Assert( this->pd, );
+         TNL_ASSERT( this->pd, );
          std::memcpy( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( Object ) );
          this->pd->maybe_modified = false;
       }
 
       bool modified()
       {
-         Assert( this->pd, );
+         TNL_ASSERT( this->pd, );
          // optimization: skip bitwise comparison if we're sure that the data is the same
          if( ! this->pd->maybe_modified )
             return false;
@@ -604,4 +614,355 @@ class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
       Object* cuda_pointer;
 };
 
+#ifdef HAVE_MIC
+/****
+ * Specialization for MIC
+ */
+template< typename Object>
+class SharedPointer< Object, Devices::MIC > : public SmartPointer
+{
+   private:
+      // Convenient template alias for controlling the selection of copy- and
+      // move-constructors and assignment operators using SFINAE.
+      // The type Object_ is "enabled" iff Object_ and Object are not the same,
+      // but after removing const and volatile qualifiers they are the same.
+      template< typename Object_ >
+      using Enabler = std::enable_if< ! std::is_same< Object_, Object >::value &&
+                                      std::is_same< typename std::remove_cv< Object >::type, Object_ >::value >;
+
+      // friend class will be needed for templated assignment operators
+      template< typename Object_, typename Device_>
+      friend class SharedPointer;
+
+   public:
+
+      typedef Object ObjectType;
+      typedef Devices::MIC DeviceType;
+      typedef SharedPointer< Object, Devices::MIC> ThisType;
+
+      template< typename... Args >
+      explicit  SharedPointer( Args... args )
+      : pd( nullptr ),
+        mic_pointer( nullptr )
+      {
+            this->allocate( args... );
+      }
+
+      // this is needed only to avoid the default compiler-generated constructor
+      SharedPointer( const ThisType& pointer )
+      : pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         this->pd->counter += 1;
+      }
+
+      // conditional constructor for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      SharedPointer( const SharedPointer< Object_, DeviceType >& pointer )
+      : pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         this->pd->counter += 1;
+      }
+
+      // this is needed only to avoid the default compiler-generated constructor
+      SharedPointer( ThisType&& pointer )
+      : pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         pointer.pd = nullptr;
+         pointer.mic_pointer = nullptr;
+      }
+
+      // conditional constructor for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      SharedPointer( SharedPointer< Object_, DeviceType >&& pointer )
+      : pd( (PointerData*) pointer.pd ),
+        mic_pointer( pointer.mic_pointer )
+      {
+         pointer.pd = nullptr;
+         pointer.mic_pointer = nullptr;
+      }
+
+      template< typename... Args >
+      bool recreate( Args... args )
+      {
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Recreating shared pointer to " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+         if( ! this->pd )
+            return this->allocate( args... );
+
+         if( this->pd->counter == 1 )
+         {
+            /****
+             * The object is not shared -> recreate it in-place, without reallocation
+             */
+            this->pd->data.~Object();
+            new ( &this->pd->data ) Object( args... );
+            Devices::MIC::CopyToMIC(this->mic_pointer,(void*) &this->pd->data,sizeof(Object));
+            this->set_last_sync_state();
+            return true;
+         }
+
+         // free will just decrement the counter
+         this->free();
+
+         return this->allocate( args... );
+      }
+
+      const Object* operator->() const
+      {
+         return &this->pd->data;
+      }
+
+      Object* operator->()
+      {
+         this->pd->maybe_modified = true;
+         return &this->pd->data;
+      }
+
+      const Object& operator *() const
+      {
+         return this->pd->data;
+      }
+
+      Object& operator *()
+      {
+         this->pd->maybe_modified = true;
+         return this->pd->data;
+      }
+
+      operator bool()
+      {
+         return this->pd;
+      }
+
+      template< typename Device = Devices::Host >
+      __cuda_callable__
+      const Object& getData() const
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+            return this->pd->data;
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );
+
+      }
+
+      template< typename Device = Devices::Host >
+      __cuda_callable__
+      Object& modifyData()
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+         {
+            this->pd->maybe_modified = true;
+            return this->pd->data;
+         }
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );
+
+      }
+
+      // this is needed only to avoid the default compiler-generated operator
+      const ThisType& operator=( const ThisType& ptr )
+      {
+         this->free();
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         this->pd->counter += 1;
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Copy-assigned shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+         return *this;
+      }
+
+      // conditional operator for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      const ThisType& operator=( const SharedPointer< Object_, DeviceType >& ptr )
+      {
+         this->free();
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         this->pd->counter += 1;
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Copy-assigned shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+         return *this;
+      }
+
+      // this is needed only to avoid the default compiler-generated operator
+      const ThisType& operator=( ThisType&& ptr )
+      {
+         this->free();
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         ptr.pd = nullptr;
+         ptr.mic_pointer = nullptr;
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Move-assigned shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+         return *this;
+      }
+
+      // conditional operator for non-const -> const data
+      template< typename Object_,
+                typename = typename Enabler< Object_ >::type >
+      const ThisType& operator=( SharedPointer< Object_, DeviceType >&& ptr )
+      {
+         this->free();
+         this->pd = (PointerData*) ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         ptr.pd = nullptr;
+         ptr.mic_pointer = nullptr;
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Move-assigned shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+         return *this;
+      }
+
+      bool synchronize()
+      {
+         if( ! this->pd )
+            return true;
+
+         if( this->modified() )
+         {
+#ifdef TNL_DEBUG_SHARED_POINTERS
+            std::cerr << "Synchronizing shared pointer: counter = " << this->pd->counter << ", type: " << demangle(typeid(Object).name()) << std::endl;
+            std::cerr << "   ( " << sizeof( Object ) << " bytes, MIC adress " << this->mic_pointer << " )" << std::endl;
+#endif
+            TNL_ASSERT( this->mic_pointer, );
+            
+            Devices::MIC::CopyToMIC((void*)this->mic_pointer,(void*) &this->pd->data,sizeof(Object));    
+            this->set_last_sync_state();
+            return true;
+         }
+         return false; //??
+      }
+      
+      void clear()
+      {
+         this->free();
+      }
+
+      ~SharedPointer()
+      {
+         this->free();
+         Devices::MIC::removeSmartPointer( this );
+      }
+
+   protected:
+
+      struct PointerData
+      {
+         Object data;
+         uint8_t data_image[ sizeof(Object) ];
+         int counter;
+         bool maybe_modified;
+
+         template< typename... Args >
+         explicit PointerData( Args... args )
+         : data( args... ),
+           counter( 1 ),
+           maybe_modified( false )
+         {}
+      };
+
+      template< typename... Args >
+      bool allocate( Args... args )
+      {
+         this->pd = new PointerData( args... );
+         if( ! this->pd )
+            return false;
+         
+         mic_pointer=(Object*)Devices::MIC::AllocMIC(sizeof(Object));
+         Devices::MIC::CopyToMIC((void*)this->mic_pointer,(void*) &this->pd->data,sizeof(Object));
+         
+         if( ! this->mic_pointer )
+            return false;
+         // set last-sync state
+         this->set_last_sync_state();
+#ifdef TNL_DEBUG_SHARED_POINTERS
+         std::cerr << "Created shared pointer to " << demangle(typeid(ObjectType).name()) << " (mic_pointer = " << this->mic_pointer << ")" << std::endl;
+#endif
+         Devices::MIC::insertSmartPointer( this );
+         return true;
+      }
+
+      void set_last_sync_state()
+      {
+         TNL_ASSERT( this->pd, );
+         std::memcpy( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( Object ) );
+         this->pd->maybe_modified = false;
+      }
+
+      bool modified()
+      {
+         TNL_ASSERT( this->pd, );
+         // optimization: skip bitwise comparison if we're sure that the data is the same
+         if( ! this->pd->maybe_modified )
+            return false;
+         return std::memcmp( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( Object ) ) != 0;
+      }
+
+      void free()
+      {
+         if( this->pd )
+         {
+#ifdef TNL_DEBUG_SHARED_POINTERS
+            std::cerr << "Freeing shared pointer: counter = " << this->pd->counter << ", mic_pointer = " << this->mic_pointer << ", type: " << demangle(typeid(ObjectType).name()) << std::endl;
+#endif
+            if( ! --this->pd->counter )
+            {
+               delete this->pd;
+               this->pd = nullptr;
+               if( this->mic_pointer )
+               {
+                   Devices::MIC::FreeMIC((void*)mic_pointer);
+                   mic_pointer=nullptr;
+               }
+#ifdef TNL_DEBUG_SHARED_POINTERS
+               std::cerr << "...deleted data." << std::endl;
+#endif
+            }
+         }
+      }
+
+      PointerData* pd;
+
+      // cuda_pointer can't be part of PointerData structure, since we would be
+      // unable to dereference this-pd on the device -- NevĂ­m zda to platĂ­ pro MIC, asi jo
+      Object* mic_pointer;
+};
+#endif
+
+
+#if  (!defined(NDEBUG)) && (!defined(HAVE_MIC)) 
+namespace Assert {
+
+template< typename Object, typename Device >
+struct Formatter< SharedPointer< Object, Device > >
+{
+   static std::string
+   printToString( const SharedPointer< Object, Device >& value )
+   {
+      ::std::stringstream ss;
+      ss << "(SharedPointer< " << Object::getType() << ", " << Device::getDeviceType()
+         << " > object at " << &value << ")";
+      return ss.str();
+   }
+};
+
+} // namespace Assert
+#endif
+
 } // namespace TNL
diff --git a/src/TNL/SmartPointersRegister.cpp b/src/TNL/SmartPointersRegister.cpp
index 7fe8a654f4a6ac6c435b4d8ccb02aadc84df37fb..03d3e058f004c201c61d7c307cce7327d5e106c9 100644
--- a/src/TNL/SmartPointersRegister.cpp
+++ b/src/TNL/SmartPointersRegister.cpp
@@ -44,7 +44,7 @@ bool SmartPointersRegister::synchronizeDevice( int deviceId )
       const auto & set = pointersOnDevices.at( deviceId );
       for( auto&& it : set )
          ( *it ).synchronize();
-      return checkCudaDevice;
+      return TNL_CHECK_CUDA_DEVICE;
    }
    catch( std::out_of_range ) {
       return false;
diff --git a/src/TNL/Solvers/BuildConfigTags.h b/src/TNL/Solvers/BuildConfigTags.h
index f479b3f9b80cd39b431561a926117073bda1aac0..e89aa9d925c7bfe748ec8ab1f98bbc8408787d18 100644
--- a/src/TNL/Solvers/BuildConfigTags.h
+++ b/src/TNL/Solvers/BuildConfigTags.h
@@ -16,6 +16,7 @@
 #include <TNL/Solvers/Linear/SOR.h>
 #include <TNL/Solvers/Linear/CG.h>
 #include <TNL/Solvers/Linear/BICGStab.h>
+#include <TNL/Solvers/Linear/BICGStabL.h>
 #include <TNL/Solvers/Linear/CWYGMRES.h>
 #include <TNL/Solvers/Linear/GMRES.h>
 #include <TNL/Solvers/Linear/TFQMR.h>
@@ -25,7 +26,7 @@
 namespace TNL {
 namespace Solvers {   
 
-class tnlDefaultBuildConfigTag{};
+class DefaultBuildConfigTag{};
 
 /****
  * All devices are enabled by default. Those which are not available
@@ -36,6 +37,10 @@ template< typename ConfigTag, typename Device > struct ConfigTagDevice{ enum { e
 template< typename ConfigTag > struct ConfigTagDevice< ConfigTag, Devices::Cuda >{ enum { enabled = false }; };
 #endif
 
+#ifndef HAVE_MIC
+template< typename ConfigTag > struct ConfigTagDevice< ConfigTag, Devices::MIC >{ enum { enabled = false }; };
+#endif
+
 /****
  * All real types are enabled by default.
  */
@@ -54,7 +59,7 @@ template< typename ConfigTag > struct ConfigTagMeshResolve{ enum { enabled = tru
 /****
  * 1, 2, and 3 dimensions are enabled by default
  */
-template< typename ConfigTag, int Dimensions > struct ConfigTagDimensions{ enum { enabled = ( Dimensions > 0 && Dimensions <= 3 ) }; };
+template< typename ConfigTag, int Dimension > struct ConfigTagDimension{ enum { enabled = ( Dimension > 0 && Dimension <= 3 ) }; };
 
 /****
  * Up to the exceptions enlisted below, all mesh types are disabled by default.
@@ -64,9 +69,9 @@ template< typename ConfigTag, typename MeshType > struct ConfigTagMesh{ enum { e
 /****
  * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
  */
-template< typename ConfigTag, int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< ConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ConfigTagDimensions< ConfigTag, Dimensions >::enabled  &&
+template< typename ConfigTag, int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< ConfigTag, Meshes::Grid< Dimension, Real, Device, Index > >
+      { enum { enabled = ConfigTagDimension< ConfigTag, Dimension >::enabled  &&
                          ConfigTagReal< ConfigTag, Real >::enabled &&
                          ConfigTagDevice< ConfigTag, Device >::enabled &&
                          ConfigTagIndex< ConfigTag, Index >::enabled }; };
@@ -133,6 +138,16 @@ public:
     using Template = Linear::BICGStab< Matrix, Preconditioner >;
 };
 
+class  SemiImplicitBICGStabLSolverTag
+{
+public:
+    template< typename Matrix,
+              typename Preconditioner = Linear::Preconditioners::Dummy< typename Matrix::RealType,
+                                                                        typename Matrix::DeviceType,
+                                                                        typename Matrix::IndexType > >
+    using Template = Linear::BICGStabL< Matrix, Preconditioner >;
+};
+
 class  SemiImplicitCWYGMRESSolverTag
 {
 public:
diff --git a/src/TNL/Solvers/CMakeLists.txt b/src/TNL/Solvers/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Solvers/FastBuildConfigTag.h b/src/TNL/Solvers/FastBuildConfigTag.h
index c0490f2ccf4a9febfa6708f996d30b4668ffc3e8..45ab71b8d84b447a178f3a1c338b1a9f4cf050ca 100644
--- a/src/TNL/Solvers/FastBuildConfigTag.h
+++ b/src/TNL/Solvers/FastBuildConfigTag.h
@@ -37,9 +37,9 @@ template<> struct ConfigTagIndex< FastBuildConfig, long int >{ enum { enabled =
 /****
  * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
  */
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< FastBuildConfig, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ConfigTagDimensions< FastBuildConfig, Dimensions >::enabled  &&
+template< int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< FastBuildConfig, Meshes::Grid< Dimension, Real, Device, Index > >
+      { enum { enabled = ConfigTagDimension< FastBuildConfig, Dimension >::enabled  &&
                          ConfigTagReal< FastBuildConfig, Real >::enabled &&
                          ConfigTagDevice< FastBuildConfig, Device >::enabled &&
                          ConfigTagIndex< FastBuildConfig, Index >::enabled }; };
diff --git a/src/TNL/Solvers/IterativeSolverMonitor.h b/src/TNL/Solvers/IterativeSolverMonitor.h
index 9dec90384a116cf1a9ae79d2cbbd1d6a3a28c47c..3180abb3c34641f7359710dd4e4d8fde44578e77 100644
--- a/src/TNL/Solvers/IterativeSolverMonitor.h
+++ b/src/TNL/Solvers/IterativeSolverMonitor.h
@@ -18,40 +18,36 @@ namespace Solvers {
 template< typename Real, typename Index>
 class IterativeSolverMonitor : public SolverMonitor
 {
-   public:
-
+public:
    typedef Index IndexType;
    typedef Real RealType;
 
    IterativeSolverMonitor();
 
+   void setStage( const std::string& stage );
+
    void setTime( const RealType& time );
 
    void setTimeStep( const RealType& timeStep );
 
-   void setStage( const std::string& stage );
-
    void setIterations( const IndexType& iterations );
 
    void setResidue( const RealType& residue );
 
    void setVerbose( const Index& verbose );
  
-   virtual void refresh( bool force = false );
-
-   protected:
+   virtual void refresh();
 
+protected:
    int getLineWidth();
 
-   RealType time;
-
-   RealType timeStep;
+   std::string stage, saved_stage;
 
-   std::string stage;
+   std::atomic_bool saved;
 
-   IndexType iterations;
+   RealType time, saved_time, timeStep, saved_timeStep, residue, saved_residue;
 
-   RealType residue;
+   IndexType iterations, saved_iterations;
 
    IndexType verbose;
 };
diff --git a/src/TNL/Solvers/IterativeSolverMonitor_impl.h b/src/TNL/Solvers/IterativeSolverMonitor_impl.h
index 6d9f6bfc7a0846ebacd18ff74bfe3abf0ddf799e..ef18320193dc83007fc87bd4e04e960f95c0ff0e 100644
--- a/src/TNL/Solvers/IterativeSolverMonitor_impl.h
+++ b/src/TNL/Solvers/IterativeSolverMonitor_impl.h
@@ -13,45 +13,66 @@
 #include <iomanip>
 #include <limits>
 
+// make sure to include the config before the check
+#include <TNL/tnlConfig.h>
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #include <unistd.h>
 #endif
 
+#include <TNL/Solvers/IterativeSolver.h>
+
 namespace TNL {
 namespace Solvers {   
 
 template< typename Real, typename Index>
 IterativeSolverMonitor< Real, Index > :: IterativeSolverMonitor()
 : SolverMonitor(),
+  stage( "" ),
+  saved_stage( "" ),
+  saved( false ),
   time( 0.0 ),
+  saved_time( 0.0 ),
   timeStep( 0.0 ),
-  stage( "" ),
+  saved_timeStep( 0.0 ),
+  residue( 0.0 ),
+  saved_residue( 0.0 ),
   iterations( 0 ),
-  residue( 0 ),
+  saved_iterations( 0 ),
   verbose( 1 )
 {
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setTime( const RealType& time )
+void IterativeSolverMonitor< Real, Index > :: setStage( const std::string& stage )
 {
-   this->time = time;
+   // save the items after a complete stage
+   if( iterations > 0 ) {
+      saved_stage = this->stage;
+      saved_time = time;
+      saved_timeStep = timeStep;
+      saved_iterations = iterations;
+      saved_residue = residue;
+   }
+
+   // reset the current items
+   iterations = 0;
+   residue = 0.0;
+
+   this->stage = stage;
+   saved = true;
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setTimeStep( const RealType& timeStep )
+void IterativeSolverMonitor< Real, Index > :: setTime( const RealType& time )
 {
-   this->timeStep = timeStep;
+   this->time = time;
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setStage( const std::string& stage )
+void IterativeSolverMonitor< Real, Index > :: setTimeStep( const RealType& timeStep )
 {
-   this->stage = stage;
-   // reset numerical items displayed after stage
-   this->iterations = 0;
-   this->residue = 0.0;
+   this->timeStep = timeStep;
 }
 
 template< typename Real, typename Index>
@@ -73,47 +94,72 @@ void IterativeSolverMonitor< Real, Index > :: setVerbose( const Index& verbose )
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: refresh( bool force )
+void IterativeSolverMonitor< Real, Index > :: refresh()
 {
-//   if( this->verbose > 0 && ( force || this->getIterations() % this->refreshRate == 0 ) )
-   if( this->verbose > 0 || force )
+   if( this->verbose > 0 )
    {
-      const int line_width = this->getLineWidth();
+      // Check if we should display the current values or the values saved after
+      // the previous stage. If the iterations cycle much faster than the solver
+      // monitor refreshes, we display only the values saved after the whole
+      // cycle to hide the irrelevant partial progress.
+      const bool saved = this->saved;
+      this->saved = false;
+
+      const int line_width = getLineWidth();
       int free = line_width ? line_width : std::numeric_limits<int>::max();
 
-      // FIXME: std::setw sets only minimum width, so free should be adjusted dynamically if more chars are actually written
-      std::cout << std::setprecision( 5 );
-      std::cout << "\33[2K\r ELA:" << std::setw( 8 ) << this->getElapsedTime()
-                << " T:"   << std::setw( 8 ) << this->time;
-      free -= 24;
-      if( this->timeStep > 0 ) {
-         std::cout << " TAU:" << std::setw( 8 ) << this->timeStep;
-         free -= 13;
+      auto real_to_string = []( Real value, int precision = 6 ) {
+         std::stringstream stream;
+         stream << std::setprecision( precision ) << value;
+         return stream.str();
+      };
+
+      auto print_item = [&free]( const std::string& item, int width = 0 ) {
+         width = min( free, (width) ? width : item.length() );
+         std::cout << std::setw( width ) << item.substr( 0, width );
+         free -= width;
+      };
+
+      // \33[2K erases the current line, see https://stackoverflow.com/a/35190285
+      std::cout << "\33[2K\r";
+
+      // FIXME: nvcc 8.0 ignores default parameter values for lambda functions in template functions, so we have to pass the defaults
+//      print_item( " ELA:" );
+      print_item( " ELA:", 0 );
+      print_item( real_to_string( getElapsedTime(), 5 ), 8 );
+//      print_item( " T:" );
+      print_item( " T:", 0 );
+      print_item( real_to_string( (saved) ? saved_time : time, 5 ), 8 );
+      if( (saved) ? saved_timeStep : timeStep > 0 ) {
+//         print_item( " TAU:" );
+         print_item( " TAU:", 0 );
+         print_item( real_to_string( (saved) ? saved_timeStep : timeStep, 5 ), 8 );
       }
 
-      if( this->stage.length() && free > 5 ) {
-         if( (int) this->stage.length() <= free - 2 ) {
-            std::cout << "  " << this->stage;
-            free -= ( 2 + this->stage.length() );
+      const std::string displayed_stage = (saved) ? saved_stage : stage;
+      if( displayed_stage.length() && free > 5 ) {
+         if( (int) displayed_stage.length() <= free - 2 ) {
+            std::cout << "  " << displayed_stage;
+            free -= ( 2 + displayed_stage.length() );
          }
          else {
-            std::cout << "  " << this->stage.substr( 0, free - 5 ) << "...";
+            std::cout << "  " << displayed_stage.substr( 0, free - 5 ) << "...";
             free = 0;
          }
       }
 
-      if( this->iterations > 0 && free >= 14 ) {
-         std::cout << " ITER:" << std::setw( 8 ) << this->iterations;
-         free -= 14;
+      if( (saved) ? saved_iterations : iterations > 0 && free >= 14 ) {
+//         print_item( " ITER:" );
+         print_item( " ITER:", 0 );
+         print_item( std::to_string( (saved) ? saved_iterations : iterations ), 8 );
       }
-      if( this->residue && free >= 17 ) {
-         std::cout << " RES:" << std::setprecision( 5 ) << std::setw( 12 ) << this->residue;
-         free -= 17;
+      if( (saved) ? saved_residue : residue && free >= 17 ) {
+//         print_item( " RES:" );
+         print_item( " RES:", 0 );
+         print_item( real_to_string( (saved) ? saved_residue : residue, 5 ), 12 );
       }
 
-      // fill the rest of the line with spaces to clear previous content
-      //while( line_width && free-- > 8 )
-      //   std::cout << " ";
+      // return to the beginning of the line
       std::cout << "\r" << std::flush;
    }
 }
diff --git a/src/TNL/Solvers/IterativeSolver_impl.h b/src/TNL/Solvers/IterativeSolver_impl.h
index 5f8c084d799c88a33f7a00c51532c9d233b810cf..9b98dbea3d308f685d6e9d2acfe701b10f1e270c 100644
--- a/src/TNL/Solvers/IterativeSolver_impl.h
+++ b/src/TNL/Solvers/IterativeSolver_impl.h
@@ -111,7 +111,7 @@ bool IterativeSolver< Real, Index> :: checkNextIteration()
        this->getIterations() > this->getMaxIterations()  ||
        ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() >= this->getMinIterations() ) ||
        ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() >= this->getMinIterations() ) )
-      return false;
+      return false;   
    return true;
 }
 
@@ -212,7 +212,6 @@ void IterativeSolver< Real, Index> :: refreshSolverMonitor( bool force )
       this->solverMonitor->setIterations( this->getIterations() );
       this->solverMonitor->setResidue( this->getResidue() );
       this->solverMonitor->setRefreshRate( this-> refreshRate );
-//      this->solverMonitor -> refresh( force );
    }
 }
 
diff --git a/src/TNL/Solvers/Linear/BICGStab.h b/src/TNL/Solvers/Linear/BICGStab.h
index b03037aca74199931eeabf0e2e68fb7fc42ef5ba..02d17965e890123968bf6059082cba0164e16f71 100644
--- a/src/TNL/Solvers/Linear/BICGStab.h
+++ b/src/TNL/Solvers/Linear/BICGStab.h
@@ -14,7 +14,6 @@
 #include <TNL/Object.h>
 #include <TNL/SharedPointer.h>
 #include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 #include <TNL/Solvers/IterativeSolver.h>
 #include <TNL/Solvers/Linear/LinearResidueGetter.h>
@@ -39,8 +38,8 @@ class BICGStab : public Object,
    typedef typename Matrix::DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
    BICGStab();
 
@@ -60,13 +59,13 @@ class BICGStab : public Object,
              typename ResidueGetter = LinearResidueGetter< Matrix, Vector >  >
    bool solve( const Vector& b, Vector& x );
 
-   ~BICGStab();
-
    protected:
 
-   bool setSize( IndexType size );
+   void setSize( IndexType size );
+
+   bool exact_residue;
 
-   Containers::Vector< RealType, DeviceType, IndexType >  r, r_ast, r_new, p, s, Ap, As, M_tmp;
+   Containers::Vector< RealType, DeviceType, IndexType > r, r_ast, p, s, Ap, As, M_tmp;
 
    MatrixPointer matrix;
    PreconditionerPointer preconditioner;
diff --git a/src/TNL/Solvers/Linear/BICGStabL.h b/src/TNL/Solvers/Linear/BICGStabL.h
new file mode 100644
index 0000000000000000000000000000000000000000..124f70839950e5565a5fb9c0a6931c08abce4509
--- /dev/null
+++ b/src/TNL/Solvers/Linear/BICGStabL.h
@@ -0,0 +1,119 @@
+/***************************************************************************
+                          BICGStabL.h  -  description
+                             -------------------
+    begin                : Jul 4, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+/*
+ * BICGStabL implements an iterative solver for non-symmetric linear systems,
+ * using the BiCGstab(l) algorithm described in [1] and [2]. It is a
+ * generalization of the stabilized biconjugate-gradient (BiCGstab) algorithm
+ * proposed by van der Vorst [3]. BiCGstab(1) is equivalent to BiCGstab, and
+ * BiCGstab(2) is a slightly more efficient version of the BiCGstab2 algorithm
+ * by Gutknecht [4], while BiCGstab(l>2) is a further generalization.
+ *
+ * This code was implemented by: Jakub Klinkovsky <klinkjak@fjfi.cvut.cz>
+ *
+ * [1] Gerard L. G. Sleijpen and Diederik R. Fokkema, "BiCGstab(l) for linear
+ *     equations involving unsymmetric matrices with complex spectrum",
+ *     Electronic Trans. on Numerical Analysis 1, 11-32 (1993).
+ * [2] Gerard L. G. Sleijpen, Henk A. van der Vorst, and Diederik R. Fokkema,
+ *     "BiCGstab(l) and other Hybrid Bi-CG Methods", Numerical Algorithms 7,
+ *     75-109 (1994).
+ * [3] Henk A. van der Vorst, "Bi-CGSTAB: A fast and smoothly converging variant
+ *     of Bi-CG for the solution of nonsymmetric linear systems, SIAM Journal on
+ *     scientific and Statistical Computing 13.2, 631-644 (1992).
+ * [4] Martin H. Gutknecht, "Variants of BiCGStab for matrices with complex
+ *     spectrum", IPS Research Report No. 91-14 (1991).
+ *
+ * TODO: further variations to explore:
+ *
+ * [5] Gerard L. G. Sleijpen and Henk A. van der Vorst, "Reliable updated
+ *     residuals in hybrid Bi-CG methods", Computing 56 (2), 141-163 (1996).
+ * [6] Gerard L. G. Sleijpen and Henk A. van der Vorst, "Maintaining convergence
+ *     properties of BiCGstab methods in finite precision arithmetic", Numerical
+ *     Algorithms 10, 203-223 (1995).
+ */
+
+#pragma once
+
+#include <math.h>
+#include <TNL/Object.h>
+#include <TNL/SharedPointer.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
+#include <TNL/Solvers/IterativeSolver.h>
+#include <TNL/Solvers/Linear/LinearResidueGetter.h>
+
+namespace TNL {
+namespace Solvers {
+namespace Linear {
+
+template< typename Matrix,
+          typename Preconditioner = Preconditioners::Dummy< typename Matrix :: RealType,
+                                                            typename Matrix :: DeviceType,
+                                                            typename Matrix :: IndexType> >
+
+class BICGStabL
+   : public Object,
+     public IterativeSolver< 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;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
+   typedef Containers::Vector< RealType, DeviceType, IndexType > DeviceVector;
+   typedef Containers::Vector< RealType, Devices::Host, IndexType > HostVector;
+
+   BICGStabL();
+
+   String getType() const;
+
+   static void configSetup( Config::ConfigDescription& config,
+                            const String& prefix = "" );
+
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );
+
+   void setMatrix( const MatrixPointer& matrix );
+
+   void setPreconditioner( const PreconditionerPointer& preconditioner );
+
+   template< typename Vector,
+             typename ResidueGetter = LinearResidueGetter< Matrix, Vector >  >
+   bool solve( const Vector& b, Vector& x );
+
+protected:
+   void setSize( IndexType size );
+
+   int ell = 1;
+
+   bool exact_residue = false;
+
+   // matrices (in column-major format)
+   DeviceVector R, U;
+   // single vectors
+   DeviceVector r_ast, M_tmp, res_tmp;
+   // host-only storage
+   HostVector T, sigma, g_0, g_1, g_2;
+
+   IndexType size, ldSize;
+
+   MatrixPointer matrix;
+   PreconditionerPointer preconditioner;
+};
+
+} // namespace Linear
+} // namespace Solvers
+} // namespace TNL
+
+#include <TNL/Solvers/Linear/BICGStabL_impl.h>
diff --git a/src/TNL/Solvers/Linear/BICGStabL_impl.h b/src/TNL/Solvers/Linear/BICGStabL_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f448e7c8835c49dd72a31e4b8e689dd09d825f85
--- /dev/null
+++ b/src/TNL/Solvers/Linear/BICGStabL_impl.h
@@ -0,0 +1,323 @@
+/***************************************************************************
+                          BICGStabL.h  -  description
+                             -------------------
+    begin                : Jul 4, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include "BICGStabL.h"
+
+#include <TNL/Matrices/MatrixOperations.h>
+
+namespace TNL {
+namespace Solvers {
+namespace Linear {
+
+template< typename Matrix,
+          typename Preconditioner >
+BICGStabL< Matrix, Preconditioner >::BICGStabL()
+{
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+String
+BICGStabL< Matrix, Preconditioner >::getType() const
+{
+   return String( "BICGStabL< " ) +
+          this->matrix -> getType() + ", " +
+          this->preconditioner -> getType() + " >";
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+void
+BICGStabL< Matrix, Preconditioner >::
+configSetup( Config::ConfigDescription& config,
+             const String& prefix )
+{
+   //IterativeSolver< RealType, IndexType >::configSetup( config, prefix );
+   config.addEntry< int >( prefix + "bicgstab-ell", "Number of Bi-CG iterations before the MR part starts.", 1 );
+   config.addEntry< bool >( prefix + "bicgstab-exact-residue", "Whether the BiCGstab should compute the exact residue in each step (true) or to use a cheap approximation (false).", false );
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+bool
+BICGStabL< Matrix, Preconditioner >::
+setup( const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   ell = parameters.getParameter< int >( "bicgstab-ell" );
+   exact_residue = parameters.getParameter< bool >( "bicgstab-exact-residue" );
+   return IterativeSolver< RealType, IndexType >::setup( parameters, prefix );
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+void
+BICGStabL< Matrix, Preconditioner >::setMatrix( const MatrixPointer& matrix )
+{
+   this->matrix = matrix;
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+void
+BICGStabL< Matrix, Preconditioner >::setPreconditioner( const PreconditionerPointer& preconditioner )
+{
+   this->preconditioner = preconditioner;
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+   template< typename Vector, typename ResidueGetter >
+bool
+BICGStabL< Matrix, Preconditioner >::solve( const Vector& b, Vector& x )
+{
+   this->setSize( matrix->getRows() );
+
+   RealType alpha, beta, gamma, rho_0, rho_1, omega, b_norm;
+   DeviceVector r_0, r_j, r_i, u_0, Au, u;
+   r_0.bind( R.getData(), size );
+   u_0.bind( U.getData(), size );
+
+   auto matvec = [this]( const DeviceVector& src, DeviceVector& dst )
+   {
+      if( preconditioner ) {
+         matrix->vectorProduct( src, M_tmp );
+         preconditioner->solve( M_tmp, dst );
+      }
+      else {
+         matrix->vectorProduct( src, dst );
+      }
+   };
+
+   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_0 );
+   }
+   else {
+      b_norm = b.lpNorm( 2.0 );
+      matrix->vectorProduct( x, r_0 );
+      r_0.addVector( b, 1.0, -1.0 );
+   }
+
+   sigma[ 0 ] = r_0.lpNorm( 2.0 );
+   if( std::isnan( sigma[ 0 ] ) )
+      throw std::runtime_error( "BiCGstab(ell): initial residue is NAN" );
+
+   r_ast = r_0;
+   r_ast /= sigma[ 0 ];
+   rho_0 = 1.0;
+   alpha = 0.0;
+   omega = 1.0;
+   u_0.setValue( 0.0 );
+
+   if( b_norm == 0.0 )
+       b_norm = 1.0;
+
+   this->resetIterations();
+   this->setResidue( sigma[ 0 ] / b_norm );
+
+   while( this->checkNextIteration() )
+   {
+      rho_0 = - omega * rho_0;
+
+      /****
+       * Bi-CG part
+       */
+      for( int j = 0; j < ell; j++ ) {
+         this->nextIteration();
+         r_j.bind( &R.getData()[ j * ldSize ], size );
+
+         rho_1 = r_ast.scalarProduct( r_j );
+         beta = alpha * rho_1 / rho_0;
+         rho_0 = rho_1;
+
+         /****
+          * U_[0:j] := R_[0:j] - beta * U_[0:j]
+          */
+         MatrixOperations< DeviceType >::
+            geam( size, j + 1,
+                  1.0, R.getData(), ldSize,
+                  -beta, U.getData(), ldSize,
+                  U.getData(), ldSize );
+
+         /****
+          * u_{j+1} = A u_j
+          */
+         u.bind( &U.getData()[ j * ldSize ], size );
+         Au.bind( &U.getData()[ (j + 1) * ldSize ], size );
+         matvec( u, Au );
+
+         gamma = r_ast.scalarProduct( Au );
+         alpha = rho_0 / gamma;
+
+         /****
+          * R_[0:j] := R_[0:j] - alpha * U_[1:j+1]
+          */
+         MatrixOperations< DeviceType >::
+            geam( size, j + 1,
+                  1.0, R.getData(), ldSize,
+                  -alpha, U.getData() + ldSize, ldSize,
+                  R.getData(), ldSize );
+
+         /****
+          * r_{j+1} = A r_j
+          */
+         r_j.bind( &R.getData()[ j * ldSize ], size );
+         r_i.bind( &R.getData()[ (j + 1) * ldSize ], size );
+         matvec( r_j, r_i );
+
+         /****
+          * x_0 := x_0 + alpha * u_0
+          */
+         x.addVector( u_0, alpha );
+      }
+
+      /****
+       * MGS part
+       */
+      for( int j = 1; j <= ell; j++ ) {
+         r_j.bind( &R.getData()[ j * ldSize ], size );
+
+         // MGS without reorthogonalization
+         for( int i = 1; i < j; i++ ) {
+            r_i.bind( &R.getData()[ i * ldSize ], size );
+            /****
+             * T_{i,j} = (r_i, r_j) / sigma_i
+             * r_j := r_j - T_{i,j} * r_i
+             */
+            const int ij = (i-1) + (j-1) * ell;
+            T[ ij ] = r_i.scalarProduct( r_j ) / sigma[ i ];
+            r_j.addVector( r_i, -T[ ij ] );
+         }
+
+         // MGS with reorthogonalization
+//         for( int i = 1; i < j; i++ ) {
+//            const int ij = (i-1) + (j-1) * ell;
+//            T[ ij ] = 0.0;
+//         }
+//         for( int l = 0; l < 2; l++ )
+//            for( int i = 1; i < j; i++ ) {
+//               r_i.bind( &R.getData()[ i * ldSize ], size );
+//               /****
+//                * T_{i,j} = (r_i, r_j) / sigma_i
+//                * r_j := r_j - T_{i,j} * r_i
+//                */
+//               const int ij = (i-1) + (j-1) * ell;
+//               const RealType T_ij = r_i.scalarProduct( r_j ) / sigma[ i ];
+//               T[ ij ] += T_ij;
+//               r_j.addVector( r_i, -T_ij );
+//            }
+
+         sigma[ j ] = r_j.scalarProduct( r_j );
+         g_1[ j ] = r_0.scalarProduct( r_j ) / sigma[ j ];
+      }
+
+      omega = g_1[ ell ];
+
+      /****
+       * g_0 = T^{-1} g_1
+       */
+      for( int j = ell; j >= 1; j-- ) {
+         g_0[ j ] = g_1[ j ];
+         for( int i = j + 1; i <= ell; i++ )
+            g_0[ j ] -= T[ (j-1) + (i-1) * ell ] * g_0[ i ];
+      }
+
+      /****
+       * g_2 = T * S * g_0,
+       * where S e_1 = 0, S e_j = e_{j-1} for j = 2, ... ell
+       */
+      for( int j = 1; j < ell; j++ ) {
+         g_2[ j ] = g_0[ j + 1 ];
+         for( int i = j + 1; i < ell; i++ )
+            g_2[ j ] += T[ (j-1) + (i-1) * ell ] * g_0[ i + 1 ];
+      }
+
+      /****
+       * Final updates
+       */
+      // x := x + R_[0:ell-1] * g_2
+      g_2[ 0 ] = g_0[ 1 ];
+      MatrixOperations< DeviceType >::gemv( size, ell,
+                                            1.0, R.getData(), ldSize, g_2.getData(),
+                                            1.0, x.getData() );
+      // r_0 := r_0 - R_[1:ell] * g_1_[1:ell]
+      MatrixOperations< DeviceType >::gemv( size, ell,
+                                            -1.0, R.getData() + ldSize, ldSize, &g_1[ 1 ],
+                                            1.0, r_0.getData() );
+      // u_0 := u_0 - U_[1:ell] * g_0_[1:ell]
+      MatrixOperations< DeviceType >::gemv( size, ell,
+                                            -1.0, U.getData() + ldSize, ldSize, &g_0[ 1 ],
+                                            1.0, u_0.getData() );
+
+      if( exact_residue ) {
+         /****
+          * Compute the exact preconditioned residue into the 's' vector.
+          */
+         if( preconditioner ) {
+            matrix->vectorProduct( x, M_tmp );
+            M_tmp.addVector( b, 1.0, -1.0 );
+            preconditioner->solve( M_tmp, res_tmp );
+         }
+         else {
+            matrix->vectorProduct( x, res_tmp );
+            res_tmp.addVector( b, 1.0, -1.0 );
+         }
+         sigma[ 0 ] = res_tmp.lpNorm( 2.0 );
+         this->setResidue( sigma[ 0 ] / b_norm );
+      }
+      else {
+         /****
+          * Use the "orthogonal residue vector" for stopping.
+          */
+         sigma[ 0 ] = r_0.lpNorm( 2.0 );
+         this->setResidue( sigma[ 0 ] / b_norm );
+      }
+   }
+
+   this->refreshSolverMonitor( true );
+   return this->checkConvergence();
+}
+
+template< typename Matrix,
+          typename Preconditioner >
+void
+BICGStabL< Matrix, Preconditioner >::setSize( IndexType size )
+{
+   this->size = ldSize = size;
+   R.setSize( (ell + 1) * ldSize );
+   U.setSize( (ell + 1) * ldSize );
+   r_ast.setSize( size );
+   M_tmp.setSize( size );
+   if( exact_residue )
+      res_tmp.setSize( size );
+   T.setSize( ell * ell );
+   sigma.setSize( ell + 1 );
+   g_0.setSize( ell + 1 );
+   g_1.setSize( ell + 1 );
+   g_2.setSize( ell + 1 );
+}
+
+} // namespace Linear
+} // namespace Solvers
+} // namespace TNL
diff --git a/src/TNL/Solvers/Linear/BICGStab_impl.h b/src/TNL/Solvers/Linear/BICGStab_impl.h
index 888ea1b77c5e55d103e751658f101b806c0ad784..adf744b50da033cd102b778189eacd68a22f9a38 100644
--- a/src/TNL/Solvers/Linear/BICGStab_impl.h
+++ b/src/TNL/Solvers/Linear/BICGStab_impl.h
@@ -10,22 +10,22 @@
 
 #pragma once
 
+#include "BICGStab.h"
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {
 
-template< typename RealType,
-          typename Vector >
-RealType computeBICGStabNewP( Vector& p,
-                              const Vector&r,
-                              const RealType& beta,
-                              const RealType& omega,
-                              const Vector& Ap );
-
 template< typename Matrix,
           typename Preconditioner >
 BICGStab< Matrix, Preconditioner > :: BICGStab()
+: exact_residue( false )
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();   
 }
 
 template< typename Matrix,
@@ -45,6 +45,7 @@ configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
    //IterativeSolver< RealType, IndexType >::configSetup( config, prefix );
+   config.addEntry< bool >( prefix + "bicgstab-exact-residue", "Whether the BiCGstab should compute the exact residue in each step (true) or to use a cheap approximation (false).", false );
 }
 
 template< typename Matrix,
@@ -54,6 +55,7 @@ BICGStab< Matrix, Preconditioner >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
+   exact_residue = parameters.getParameter< bool >( "bicgstab-exact-residue" );
    return IterativeSolver< RealType, IndexType >::setup( parameters, prefix );
 }
 
@@ -76,141 +78,129 @@ template< typename Matrix,
    template< typename Vector, typename ResidueGetter >
 bool BICGStab< Matrix, Preconditioner >::solve( const Vector& b, Vector& x )
 {
-   if( ! this->setSize( matrix->getRows() ) ) return false;
-
-   this->resetIterations();
-   this->setResidue( this->getConvergenceResidue() + 1.0 );
+   this->setSize( matrix->getRows() );
 
-   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
+   RealType alpha, beta, omega, aux, rho, rho_old, b_norm;
 
-   this->matrix -> vectorProduct( x, r );
+   if( preconditioner ) {
+      preconditioner->solve( b, M_tmp );
+      b_norm = M_tmp.lpNorm( ( RealType ) 2.0 );
 
-   //if( bNorm == 0.0 ) bNorm = 1.0;
-
-   /*if( M )
-   {
-      M -> Solve( b, M_tmp );
-      for( i = 0; i < size; i ++ )
-         b_norm += M_tmp[ i ] * M_tmp[ i ];
-
-      for( i = 0; i < size; i ++ )
-         M_tmp[ i ] =  b[ i ] - r[ i ];
-      M -> Solve( M_tmp, r );
-      for( i = 0; i < size; i ++ )
-      {
-         r_ast[ i ] = p[ i ] = r[ i ];
-         rho += r[ i ] * r_ast[ i ];
-      }
+      matrix->vectorProduct( x, M_tmp );
+      M_tmp.addVector( b, 1.0, -1.0 );
+      preconditioner->solve( M_tmp, r );
    }
-   else*/
-   {
+   else {
+      b_norm = b.lpNorm( 2.0 );
+      matrix->vectorProduct( x, r );
       r.addVector( b, 1.0, -1.0 );
-      p = r_ast = r;
-      rho = r.scalarProduct( r_ast );
-      bNorm = b.lpNorm( 2.0 );
    }
 
+   p = r_ast = r;
+   s.setValue( 0.0 );
+   rho = r.scalarProduct( r_ast );
+
+   if( b_norm == 0.0 )
+       b_norm = 1.0;
+
+   this->resetIterations();
+   this->setResidue( std::sqrt( rho ) / b_norm );
+
    while( this->nextIteration() )
    {
       /****
        * alpha_j = ( r_j, r^ast_0 ) / ( A * p_j, r^ast_0 )
        */
-      /*if( M ) // preconditioner
-      {
-         A. vectorProduct( p, M_tmp );
-         M -> Solve( M_tmp, Ap );
+      if( preconditioner ) {
+         matrix->vectorProduct( p, M_tmp );
+         preconditioner->solve( M_tmp, Ap );
       }
-      else*/
-          this->matrix -> vectorProduct( p, Ap );
-
-      //dbgCout( "Computing alpha" );
-      s2 = Ap.scalarProduct( r_ast );
-      if( s2 == 0.0 ) alpha = 0.0;
-      else alpha = rho / s2;
+      else {
+         matrix->vectorProduct( p, Ap );
+      }
+      aux = Ap.scalarProduct( r_ast );
+      alpha = rho / aux;
 
       /****
        * s_j = r_j - alpha_j * A p_j
        */
-      s.addVectors( r, 1.0, Ap, -alpha );
+      s.addVectors( r, 1.0, Ap, -alpha, 0.0 );
 
       /****
        * omega_j = ( A s_j, s_j ) / ( A s_j, A s_j )
        */
-      /*if( M ) // preconditioner
-      {
-         A. vectorProduct( s, M_tmp );
-         DrawVector( "As", M_tmp, ( m_int ) ::sqrt( ( m_real ) size ) );
-         M -> Solve( M_tmp, As );
+      if( preconditioner ) {
+         matrix->vectorProduct( s, M_tmp );
+         preconditioner->solve( M_tmp, As );
       }
-      else*/
-          this->matrix -> vectorProduct( s, As );
-
-      s1 = As. scalarProduct( s );
-      s2 = As. scalarProduct( As );
-      if( s2 == 0.0 ) omega = 0.0;
-      else omega = s1 / s2;
+      else {
+         matrix->vectorProduct( s, As );
+      }
+      aux = As.lpNorm( 2.0 );
+      omega = As.scalarProduct( s ) / ( aux * aux );
 
       /****
        * x_{j+1} = x_j + alpha_j * p_j + omega_j * s_j
        */
       x.addVectors( p, alpha, s, omega );
-      
+
       /****
-       * r_{j+1} = s_j - omega_j * A * s_j
+       * r_{j+1} = s_j - omega_j * A s_j
        */
-      r.addVectors( s, 1.0, As, -omega );
+      r.addVectors( s, 1.0, As, -omega, 0.0 );
 
       /****
        * beta = alpha_j / omega_j * ( r_{j+1}, r^ast_0 ) / ( r_j, r^ast_0 )
        */
-      s1 = 0.0;
-      s1 = r. scalarProduct( r_ast );
-      if( rho == 0.0 ) beta = 0.0;
-      else beta = ( s1 / rho ) * ( alpha / omega );
-      rho = s1;
+      rho_old = rho;
+      rho = r.scalarProduct( r_ast );
+      beta = ( rho / rho_old ) * ( alpha / omega );
 
       /****
        * p_{j+1} = r_{j+1} + beta_j * ( p_j - omega_j * A p_j )
        */
       p.addVectors( r, 1.0, Ap, -beta * omega, beta );
-      RealType residue = r.lpNorm( 2.0 );
-      //RealType residue = computeBICGStabNewP( p, r, beta, omega, Ap );
 
-      residue /= bNorm;
-      this->setResidue( residue );
-      if( this->getIterations() % 10 == 0 )
-         this->setResidue( ResidueGetter::getResidue( *matrix, b, x, bNorm ) );
+      if( exact_residue ) {
+         /****
+          * Compute the exact preconditioned residue into the 's' vector.
+          */
+         if( preconditioner ) {
+            matrix->vectorProduct( x, M_tmp );
+            M_tmp.addVector( b, 1.0, -1.0 );
+            preconditioner->solve( M_tmp, s );
+         }
+         else {
+            matrix->vectorProduct( x, s );
+            s.addVector( b, 1.0, -1.0 );
+         }
+         const RealType residue = s.lpNorm( 2.0 );
+         this->setResidue( residue / b_norm );
+      }
+      else {
+         /****
+          * Use the "orthogonal residue vector" for stopping.
+          */
+         const RealType residue = r.lpNorm( 2.0 );
+         this->setResidue( residue / b_norm );
+      }
    }
-   //this->setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
+
    this->refreshSolverMonitor( true );
    return this->checkConvergence();
 }
 
 template< typename Matrix,
           typename Preconditioner >
-BICGStab< Matrix, Preconditioner > :: ~BICGStab()
+void BICGStab< Matrix, Preconditioner > :: setSize( IndexType size )
 {
-}
-
-template< typename Matrix,
-          typename Preconditioner >
-bool BICGStab< Matrix, Preconditioner > :: setSize( IndexType size )
-{
-   if( ! r. setSize( size ) ||
-       ! r_ast. setSize( size ) ||
-       ! p. setSize( size ) ||
-       ! s. setSize( size ) ||
-       ! Ap. setSize( size ) ||
-       ! As. setSize( size ) ||
-       ! M_tmp. setSize( size ) )
-   {
-      std::cerr << "I am not able to allocate all supporting arrays for the BICGStab solver." << std::endl;
-      return false;
-   }
-   return true;
-
+   r.setSize( size );
+   r_ast.setSize( size );
+   p.setSize( size );
+   s.setSize( size );
+   Ap.setSize( size );
+   As.setSize( size );
+   M_tmp.setSize( size );
 }
 
 } // namespace Linear
diff --git a/src/TNL/Solvers/Linear/CG.h b/src/TNL/Solvers/Linear/CG.h
index ac1f33fe46706f042f10ba61a58b238561ca26ea..670303873d401e489ae55740b35905ab1914371b 100644
--- a/src/TNL/Solvers/Linear/CG.h
+++ b/src/TNL/Solvers/Linear/CG.h
@@ -14,7 +14,6 @@
 #include <TNL/Object.h>
 #include <TNL/SharedPointer.h>
 #include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 #include <TNL/Solvers/IterativeSolver.h>
 #include <TNL/Solvers/Linear/LinearResidueGetter.h>
@@ -38,8 +37,8 @@ class CG : public Object,
    typedef typename Matrix::DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
 
    CG();
@@ -60,11 +59,9 @@ class CG : public Object,
              typename ResidueGetter = LinearResidueGetter< Matrix, Vector >  >
    bool solve( const Vector& b, Vector& x );
 
-   ~CG();
-
    protected:
 
-   bool setSize( IndexType size );
+   void setSize( IndexType size );
 
    Containers::Vector< RealType, DeviceType, IndexType >  r, new_r, p, Ap;
 
diff --git a/src/TNL/Solvers/Linear/CG_impl.h b/src/TNL/Solvers/Linear/CG_impl.h
index f1d8b10bddfcd7b77494480e3ee8ff7fe3ca38ff..4c11c224e5c0b4f73c45a82146862473b9fc6488 100644
--- a/src/TNL/Solvers/Linear/CG_impl.h
+++ b/src/TNL/Solvers/Linear/CG_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include "CG.h"
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {
@@ -18,6 +20,11 @@ template< typename Matrix,
           typename Preconditioner >
 CG< Matrix, Preconditioner > :: CG()
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();   
 }
 
 template< typename Matrix,
@@ -70,7 +77,7 @@ bool
 CG< Matrix, Preconditioner >::
 solve( const Vector& b, Vector& x )
 {
-   if( ! this->setSize( matrix->getRows() ) ) return false;
+   this->setSize( matrix->getRows() );
 
    this->resetIterations();
    this->setResidue( this->getConvergenceResidue() + 1.0 );
@@ -135,33 +142,22 @@ solve( const Vector& b, Vector& x )
       new_r.swap( r );
  
       if( this->getIterations() % 10 == 0 )
-         this->setResidue( ResidueGetter::getResidue( *matrix, b, x, bNorm ) );
+         this->setResidue( ResidueGetter::getResidue( *matrix, x, b, bNorm ) );
    }
-   this->setResidue( ResidueGetter::getResidue( *matrix, b, x, bNorm ) );
+   this->setResidue( ResidueGetter::getResidue( *matrix, x, b, bNorm ) );
    this->refreshSolverMonitor( true );
    return this->checkConvergence();
-};
-
-template< typename Matrix,
-          typename Preconditioner >
-CG< Matrix, Preconditioner > :: ~CG()
-{
-};
+}
 
 template< typename Matrix,
           typename Preconditioner >
-bool CG< Matrix, Preconditioner > :: setSize( IndexType size )
+void CG< Matrix, Preconditioner > :: setSize( IndexType size )
 {
-   if( ! r. setSize( size ) ||
-       ! new_r. setSize( size ) ||
-       ! p. setSize( size ) ||
-       ! Ap. setSize( size ) )
-   {
-      std::cerr << "I am not able to allocated all supporting arrays for the CG solver." << std::endl;
-      return false;
-   }
-   return true;
-};
+   r.setSize( size );
+   new_r.setSize( size );
+   p.setSize( size );
+   Ap.setSize( size );
+}
 
 } // namespace Linear
 } // namespace Solvers
diff --git a/src/TNL/Solvers/Linear/CMakeLists.txt b/src/TNL/Solvers/Linear/CMakeLists.txt
old mode 100755
new mode 100644
index 01e22b367b23872fcddb76ba6d6c7a42d1af36a6..2321264a86c29551aeefffddcf930c9b3eac8077
--- a/src/TNL/Solvers/Linear/CMakeLists.txt
+++ b/src/TNL/Solvers/Linear/CMakeLists.txt
@@ -2,6 +2,8 @@ ADD_SUBDIRECTORY( Preconditioners )
 
 SET( headers BICGStab.h
              BICGStab_impl.h
+             BICGStabL.h
+             BICGStabL_impl.h
              CG.h
              CG_impl.h
              CWYGMRES.h
diff --git a/src/TNL/Solvers/Linear/CWYGMRES.h b/src/TNL/Solvers/Linear/CWYGMRES.h
index 7e909b0e187416d5b48608f83b83da232027a49d..fd7b4dbef3af1fe71202d6942403ba244a2d43d3 100644
--- a/src/TNL/Solvers/Linear/CWYGMRES.h
+++ b/src/TNL/Solvers/Linear/CWYGMRES.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          CWYGMRES.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <math.h>
@@ -27,8 +39,8 @@ public:
    typedef typename Matrix::DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
    typedef Containers::Vector< RealType, DeviceType, IndexType > DeviceVector;
    typedef Containers::Vector< RealType, Devices::Host, IndexType > HostVector;
 
@@ -96,7 +108,7 @@ protected:
                             RealType& sn );
 
 
-   bool setSize( IndexType _size, IndexType m );
+   void setSize( IndexType _size, IndexType m );
 
    // single vectors
    DeviceVector r, z, w, _M_tmp;
@@ -107,7 +119,7 @@ protected:
    // host-only storage for Givens rotations and the least squares problem
    HostVector cs, sn, H, s;
 
-   IndexType size, ldSize, restarting;
+   IndexType size, ldSize, restarting_min, restarting_max, restarting_step_min, restarting_step_max;
 
    MatrixPointer matrix;
    PreconditionerPointer preconditioner;
diff --git a/src/TNL/Solvers/Linear/CWYGMRES_impl.h b/src/TNL/Solvers/Linear/CWYGMRES_impl.h
index 988e7b9ddc0a844fc12ed2d1927a29b999fc0b80..01f966faa5b1df7298bdd603db893b79210ec310 100644
--- a/src/TNL/Solvers/Linear/CWYGMRES_impl.h
+++ b/src/TNL/Solvers/Linear/CWYGMRES_impl.h
@@ -1,7 +1,20 @@
+/***************************************************************************
+                          CWYGMRES.h  -  description
+                             -------------------
+    begin                : May 13, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <type_traits>
 
+#include <TNL/Exceptions/CudaSupportMissing.h>
 #include <TNL/Containers/Algorithms/Multireduction.h>
 #include <TNL/Matrices/MatrixOperations.h>
 
@@ -17,8 +30,16 @@ CWYGMRES< Matrix, Preconditioner >::
 CWYGMRES()
 : size( 0 ),
   ldSize( 0 ),
-  restarting( 10 )
+  restarting_min( 10 ),
+  restarting_max( 10 ),
+  restarting_step_min( 3 ),
+  restarting_step_max( 3 )
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();   
 }
 
 template< typename Matrix,
@@ -47,7 +68,10 @@ configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
    //IterativeSolver< RealType, IndexType >::configSetup( config, prefix );
-   config.addEntry< int >( prefix + "gmres-restarting", "Number of iterations after which the CWYGMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-min", "Minimal number of iterations after which the GMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-max", "Maximal number of iterations after which the GMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-step-min", "Minimal adjusting step for the adaptivity of the GMRES restarting parameter.", 3 );
+   config.addEntry< int >( prefix + "gmres-restarting-step-max", "Maximal adjusting step for the adaptivity of the GMRES restarting parameter.", 3 );
 }
 
 template< typename Matrix,
@@ -58,7 +82,10 @@ setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
    IterativeSolver< RealType, IndexType >::setup( parameters, prefix );
-   this->setRestarting( parameters.getParameter< int >( "gmres-restarting" ) );
+   restarting_min = parameters.getParameter< int >( "gmres-restarting-min" );
+   this->setRestarting( parameters.getParameter< int >( "gmres-restarting-max" ) );
+   restarting_step_min = parameters.getParameter< int >( "gmres-restarting-step-min" );
+   restarting_step_max = parameters.getParameter< int >( "gmres-restarting-step-max" );
    return true;
 }
 
@@ -70,7 +97,7 @@ setRestarting( IndexType rest )
 {
    if( size != 0 )
       setSize( size, rest );
-   restarting = rest;
+   restarting_max = rest;
 }
 
 template< typename Matrix,
@@ -98,18 +125,20 @@ bool
 CWYGMRES< Matrix, Preconditioner >::
 solve( const Vector& b, Vector& x )
 {
-   Assert( matrix, std::cerr << "No matrix was set in CWYGMRES. Call setMatrix() before solve()." << std::endl );
-   if( restarting <= 0 )
+   TNL_ASSERT_TRUE( matrix, "No matrix was set in CWYGMRES. Call setMatrix() before solve()." );
+   if( restarting_min <= 0 || restarting_max <= 0 || restarting_min > restarting_max )
    {
-      std::cerr << "I have wrong value for the restarting of the CWYGMRES solver. It is set to " << restarting
-           << ". Please set some positive value using the SetRestarting method." << std::endl;
+      std::cerr << "Wrong value for the GMRES restarting parameters: r_min = " << restarting_min
+                << ", r_max = " << restarting_max << std::endl;
       return false;
    }
-   if( ! setSize( matrix -> getRows(), restarting ) )
+   if( restarting_step_min < 0 || restarting_step_max < 0 || restarting_step_min > restarting_step_max )
    {
-      std::cerr << "I am not able to allocate enough memory for the CWYGMRES solver. You may try to decrease the restarting parameter." << std::endl;
-       return false;
+      std::cerr << "Wrong value for the GMRES restarting adjustment parameters: d_min = " << restarting_step_min
+                << ", d_max = " << restarting_step_max << std::endl;
+      return false;
    }
+   setSize( matrix -> getRows(), restarting_max );
 
    RealType normb( 0.0 ), beta( 0.0 );
    /****
@@ -143,10 +172,37 @@ solve( const Vector& b, Vector& x )
    this->resetIterations();
    this->setResidue( beta / normb );
 
+   // parameters for the adaptivity of the restarting parameter
+         RealType beta_ratio = 1;           // = beta / beta_ratio (small value indicates good convergence rate)
+   const RealType max_beta_ratio = 0.99;    // = cos(8°) \approx 0.99
+   const RealType min_beta_ratio = 0.175;   // = cos(80°) \approx 0.175
+         int restart_cycles = 0;    // counter of restart cycles
+         int m = restarting_max;    // current restarting parameter
+
    DeviceVector vi, vk;
    while( this->checkNextIteration() )
    {
-      const IndexType m = restarting;
+      // adaptivity of the restarting parameter
+      // reference:  A.H. Baker, E.R. Jessup, Tz.V. Kolev - A simple strategy for varying the restart parameter in GMRES(m)
+      //             http://www.sciencedirect.com/science/article/pii/S0377042709000132
+      if( restart_cycles > 0 ) {
+         if( beta_ratio > max_beta_ratio )
+            // near stagnation -> set maximum
+            m = restarting_max;
+         else if( beta_ratio >= min_beta_ratio ) {
+            // the step size is determined based on current m using linear interpolation
+            // between restarting_step_min and restarting_step_max
+            const int step = restarting_step_min + (float) ( restarting_step_max - restarting_step_min ) /
+                                                           ( restarting_max - restarting_min ) *
+                                                           ( m - restarting_min );
+            if( m - step >= restarting_min )
+               m -= step;
+            else
+               // set restarting_max when we hit restarting_min (see Baker et al. (2009))
+               m = restarting_max;
+         }
+//         std::cerr << "restarting: cycle = " << restart_cycles << ", beta_ratio = " << beta_ratio << ", m = " << m << "    " << std::endl;
+      }
 
       /***
        * z = r / | r | =  1.0 / beta * r
@@ -278,6 +334,7 @@ solve( const Vector& b, Vector& x )
       /****
        * r = M.solve(b - A * x);
        */
+      const RealType beta_old = beta;
       if( preconditioner )
       {
          matrix->vectorProduct( x, _M_tmp );
@@ -296,6 +353,9 @@ solve( const Vector& b, Vector& x )
 //      cout << " beta = " << beta << endl;
 //      cout << "residue = " << beta / normb << endl;
 
+      // update parameters for the adaptivity of the restarting parameter
+      ++restart_cycles;
+      beta_ratio = beta / beta_old;
    }
    this->refreshSolverMonitor( true );
    return this->checkConvergence();
@@ -358,9 +418,9 @@ hauseholder_generate( DeviceVector& Y,
                                                             z.getData(),
                                                             i,
                                                             size );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
 #else
-      CudaSupportMissingMessage;
+      throw Exceptions::CudaSupportMissing();
 #endif
    }
 
@@ -384,7 +444,7 @@ hauseholder_generate( DeviceVector& Y,
    // assuming it's stable enough...
    const RealType t_i = 2.0 / (norm_yi * norm_yi);
 
-   T[ i + i * (restarting + 1) ] = t_i;
+   T[ i + i * (restarting_max + 1) ] = t_i;
    if( i > 0 ) {
       // aux = Y_{i-1}^T * y_i
       RealType aux[ i ];
@@ -404,9 +464,9 @@ hauseholder_generate( DeviceVector& Y,
 
       // [T_i]_{0..i-1} = - T_{i-1} * t_i * aux
       for( int k = 0; k < i; k++ ) {
-         T[ k + i * (restarting + 1) ] = 0.0;
+         T[ k + i * (restarting_max + 1) ] = 0.0;
          for( int j = k; j < i; j++ )
-            T[ k + i * (restarting + 1) ] -= T[ k + j * (restarting + 1) ] * (t_i * aux[ j ]);
+            T[ k + i * (restarting_max + 1) ] -= T[ k + j * (restarting_max + 1) ] * (t_i * aux[ j ]);
       }
    }
 }
@@ -424,7 +484,7 @@ hauseholder_apply_trunc( HostVector& out,
    DeviceVector y_i;
    y_i.bind( &Y.getData()[ i * ldSize ], size );
 
-   const RealType aux = T[ i + i * (restarting + 1) ] * y_i.scalarProduct( z );
+   const RealType aux = T[ i + i * (restarting_max + 1) ] * y_i.scalarProduct( z );
    if( std::is_same< DeviceType, Devices::Host >::value ) {
       for( int k = 0; k <= i; k++ )
          out[ k ] = z[ k ] - y_i[ k ] * aux;
@@ -432,10 +492,10 @@ hauseholder_apply_trunc( HostVector& out,
    if( std::is_same< DeviceType, Devices::Cuda >::value ) {
       // copy part of y_i to buffer on host
       // here we duplicate the upper (m+1)x(m+1) submatrix of Y on host for fast access
-      RealType* host_yi = &YL[ i * (restarting + 1) ];
+      RealType* host_yi = &YL[ i * (restarting_max + 1) ];
       RealType host_z[ i + 1 ];
-      if( ! Containers::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( host_yi, y_i.getData(), restarting + 1 ) ||
-          ! Containers::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( host_z, z.getData(), i + 1 ) )
+      if( ! Containers::Algorithms::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( host_yi, y_i.getData(), restarting_max + 1 ) ||
+          ! Containers::Algorithms::ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< RealType, RealType, IndexType >( host_z, z.getData(), i + 1 ) )
       {
          std::cerr << "Failed to copy part of device vectors y_i or z to host buffer." << std::endl;
          throw 1;
@@ -463,7 +523,7 @@ hauseholder_cwy( DeviceVector& v,
    if( std::is_same< DeviceType, Devices::Cuda >::value ) {
       // the upper (m+1)x(m+1) submatrix of Y is duplicated on host for fast access
       for( int k = 0; k <= i; k++ )
-         aux[ k ] = YL[ i + k * (restarting + 1) ];
+         aux[ k ] = YL[ i + k * (restarting_max + 1) ];
    }
 
    // aux = T_i * aux
@@ -471,7 +531,7 @@ hauseholder_cwy( DeviceVector& v,
    for( int k = 0; k <= i; k++ ) {
       RealType aux2 = 0.0;
       for( int j = k; j <= i; j++ )
-         aux2 += T[ k + j * (restarting + 1) ] * aux[ j ];
+         aux2 += T[ k + j * (restarting_max + 1) ] * aux[ j ];
       aux[ k ] = aux2;
    }
 
@@ -513,7 +573,7 @@ hauseholder_cwy_transposed( DeviceVector& z,
    for( int k = i; k >= 0; k-- ) {
       RealType aux2 = 0.0;
       for( int j = 0; j <= k; j++ )
-         aux2 += T[ j + k * (restarting + 1) ] * aux[ j ];
+         aux2 += T[ j + k * (restarting_max + 1) ] * aux[ j ];
       aux[ k ] = aux2;
    }
 
@@ -612,30 +672,30 @@ applyPlaneRotation( RealType& dx,
 
 template< typename Matrix,
           typename Preconditioner >
-bool CWYGMRES< Matrix, Preconditioner > :: setSize( IndexType _size, IndexType m )
+void CWYGMRES< Matrix, Preconditioner > :: setSize( IndexType _size, IndexType m )
 {
-   if( size == _size && restarting == m ) return true;
+   if( size == _size && restarting_max == m )
+      return;
    size = _size;
-   // align each column to 256 bytes
-   ldSize = roundToMultiple( size, 256 / sizeof( RealType ) );
-   restarting = m;
-   if( ! r.setSize( size ) ||
-       ! z.setSize( size ) ||
-       ! w.setSize( size ) ||
-       ! V.setSize( ldSize * ( restarting + 1 ) ) ||
-       ! Y.setSize( ldSize * ( restarting + 1 ) ) ||
-       ! T.setSize( (restarting + 1) * (restarting + 1) ) ||
-       ! YL.setSize( (restarting + 1) * (restarting + 1) ) ||
-       ! cs.setSize( restarting + 1 ) ||
-       ! sn.setSize( restarting + 1 ) ||
-       ! H.setSize( ( restarting + 1 ) * restarting ) ||
-       ! s.setSize( restarting + 1 ) ||
-       ! _M_tmp.setSize( size ) )
-   {
-      std::cerr << "I could not allocate all supporting arrays for the CWYGMRES solver." << std::endl;
-      return false;
-   }
-   return true;
+   if( std::is_same< DeviceType, Devices::Cuda >::value )
+      // align each column to 256 bytes - optimal for CUDA
+      ldSize = roundToMultiple( size, 256 / sizeof( RealType ) );
+   else
+       // on the host, we add 1 to disrupt the cache false-sharing pattern
+      ldSize = roundToMultiple( size, 256 / sizeof( RealType ) ) + 1;
+   restarting_max = m;
+   r.setSize( size );
+   z.setSize( size );
+   w.setSize( size );
+   V.setSize( ldSize * ( m + 1 ) );
+   Y.setSize( ldSize * ( m + 1 ) );
+   T.setSize( (m + 1) * (m + 1) );
+   YL.setSize( (m + 1) * (m + 1) );
+   cs.setSize( m + 1 );
+   sn.setSize( m + 1 );
+   H.setSize( ( m + 1 ) * m );
+   s.setSize( m + 1 );
+   _M_tmp.setSize( size );
 }
 
 } // namespace Linear
diff --git a/src/TNL/Solvers/Linear/GMRES.h b/src/TNL/Solvers/Linear/GMRES.h
index d36d6527e4cc582bd9466f505bff219211bb75e1..845f9399503c0981f0f608e9b685ce8be508b594 100644
--- a/src/TNL/Solvers/Linear/GMRES.h
+++ b/src/TNL/Solvers/Linear/GMRES.h
@@ -37,8 +37,8 @@ public:
    typedef typename Matrix::DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
    GMRES();
 
@@ -82,14 +82,15 @@ protected:
                             RealType& sn );
 
 
-   bool setSize( IndexType _size, IndexType m );
+   void setSize( IndexType _size, IndexType m );
 
    Containers::Vector< RealType, DeviceType, IndexType > _r, w, _v, _M_tmp;
    Containers::Vector< RealType, Devices::Host, IndexType > _s, _cs, _sn, _H;
 
-   IndexType size, restarting;
+   IndexType size, restarting_min, restarting_max, restarting_step_min, restarting_step_max;
 
    MatrixPointer matrix;
+   
    PreconditionerPointer preconditioner;
 };
 
diff --git a/src/TNL/Solvers/Linear/GMRES_impl.cpp b/src/TNL/Solvers/Linear/GMRES_impl.cpp
index 3bf16b3ee99df843aaa1f402497c377c7ca81f02..de639a5c219d0743951e0ebac8abb2a28b726864 100644
--- a/src/TNL/Solvers/Linear/GMRES_impl.cpp
+++ b/src/TNL/Solvers/Linear/GMRES_impl.cpp
@@ -8,6 +8,8 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
+
 #include <TNL/Solvers/Linear/GMRES.h>
 #include <TNL/Matrices/CSR.h>
 #include <TNL/Matrices/Ellpack.h>
@@ -53,3 +55,5 @@ template class GMRES< Matrices::Multidiagonal< double, Devices::Cuda, long int >
 } // namespace Linear
 } // namespace Solvers
 } // namespace TNL
+
+#endif // #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Solvers/Linear/GMRES_impl.h b/src/TNL/Solvers/Linear/GMRES_impl.h
index 5fef76b9bdf590f3f849c8f2597e90621d77681b..d3a20175926d9023228152f91a24ac04154fc80c 100644
--- a/src/TNL/Solvers/Linear/GMRES_impl.h
+++ b/src/TNL/Solvers/Linear/GMRES_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include "GMRES.h"
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {
@@ -19,8 +21,16 @@ template< typename Matrix,
 GMRES< Matrix, Preconditioner >::
 GMRES()
 : size( 0 ),
-  restarting( 10 )
+  restarting_min( 10 ),
+  restarting_max( 10 ),
+  restarting_step_min( 3 ),
+  restarting_step_max( 3 )
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();
 }
 
 template< typename Matrix,
@@ -49,7 +59,10 @@ configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
    //IterativeSolver< RealType, IndexType >::configSetup( config, prefix );
-   config.addEntry< int >( prefix + "gmres-restarting", "Number of iterations after which the GMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-min", "Minimal number of iterations after which the GMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-max", "Maximal number of iterations after which the GMRES restarts.", 10 );
+   config.addEntry< int >( prefix + "gmres-restarting-step-min", "Minimal adjusting step for the adaptivity of the GMRES restarting parameter.", 3 );
+   config.addEntry< int >( prefix + "gmres-restarting-step-max", "Maximal adjusting step for the adaptivity of the GMRES restarting parameter.", 3 );
 }
 
 template< typename Matrix,
@@ -60,7 +73,10 @@ setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
    IterativeSolver< RealType, IndexType >::setup( parameters, prefix );
-   this->setRestarting( parameters.getParameter< int >( "gmres-restarting" ) );
+   restarting_min = parameters.getParameter< int >( "gmres-restarting-min" );
+   this->setRestarting( parameters.getParameter< int >( "gmres-restarting-max" ) );
+   restarting_step_min = parameters.getParameter< int >( "gmres-restarting-step-min" );
+   restarting_step_max = parameters.getParameter< int >( "gmres-restarting-step-max" );
    return true;
 }
 
@@ -72,7 +88,7 @@ setRestarting( IndexType rest )
 {
    if( size != 0 )
       setSize( size, rest );
-   restarting = rest;
+   restarting_max = rest;
 }
 
 template< typename Matrix,
@@ -100,18 +116,20 @@ bool
 GMRES< Matrix, Preconditioner >::
 solve( const Vector& b, Vector& x )
 {
-   Assert( matrix, std::cerr << "No matrix was set in GMRES. Call setMatrix() before solve()." << std::endl );
-   if( restarting <= 0 )
+   TNL_ASSERT_TRUE( matrix, "No matrix was set in GMRES. Call setMatrix() before solve()." );
+   if( restarting_min <= 0 || restarting_max <= 0 || restarting_min > restarting_max )
    {
-      std::cerr << "I have wrong value for the restarting of the GMRES solver. It is set to " << restarting
-           << ". Please set some positive value using the SetRestarting method." << std::endl;
+      std::cerr << "Wrong value for the GMRES restarting parameters: r_min = " << restarting_min
+                << ", r_max = " << restarting_max << std::endl;
       return false;
    }
-   if( ! setSize( matrix -> getRows(), restarting ) )
+   if( restarting_step_min < 0 || restarting_step_max < 0 || restarting_step_min > restarting_step_max )
    {
-       std::cerr << "I am not able to allocate enough memory for the GMRES solver. You may try to decrease the restarting parameter." << std::endl;
-       return false;
+      std::cerr << "Wrong value for the GMRES restarting adjustment parameters: d_min = " << restarting_step_min
+                << ", d_max = " << restarting_step_max << std::endl;
+      return false;
    }
+   setSize( matrix -> getRows(), restarting_max );
 
    IndexType _size = size;
  
@@ -154,10 +172,38 @@ solve( const Vector& b, Vector& x )
    this->resetIterations();
    this->setResidue( beta / normb );
 
+   // parameters for the adaptivity of the restarting parameter
+         RealType beta_ratio = 1;           // = beta / beta_ratio (small value indicates good convergence rate)
+   const RealType max_beta_ratio = 0.99;    // = cos(8°) \approx 0.99
+   const RealType min_beta_ratio = 0.175;   // = cos(80°) \approx 0.175
+         int restart_cycles = 0;    // counter of restart cycles
+         int m = restarting_max;    // current restarting parameter
+
    Containers::Vector< RealType, DeviceType, IndexType > vi, vk;
    while( this->checkNextIteration() )
    {
-      const IndexType m = restarting;
+      // adaptivity of the restarting parameter
+      // reference:  A.H. Baker, E.R. Jessup, Tz.V. Kolev - A simple strategy for varying the restart parameter in GMRES(m)
+      //             http://www.sciencedirect.com/science/article/pii/S0377042709000132
+      if( restarting_max > restarting_min && restart_cycles > 0 ) {
+         if( beta_ratio > max_beta_ratio )
+            // near stagnation -> set maximum
+            m = restarting_max;
+         else if( beta_ratio >= min_beta_ratio ) {
+            // the step size is determined based on current m using linear interpolation
+            // between restarting_step_min and restarting_step_max
+            const int step = restarting_step_min + (float) ( restarting_step_max - restarting_step_min ) /
+                                                           ( restarting_max - restarting_min ) *
+                                                           ( m - restarting_min );
+            if( m - step >= restarting_min )
+               m -= step;
+            else
+               // set restarting_max when we hit restarting_min (see Baker et al. (2009))
+               m = restarting_max;
+         }
+//         std::cerr << "restarting: cycle = " << restart_cycles << ", beta_ratio = " << beta_ratio << ", m = " << m << "    " << std::endl;
+      }
+
       for( IndexType i = 0; i < m + 1; i ++ )
          H[ i ] = s[ i ] = cs[ i ] = sn[ i ] = 0.0;
 
@@ -272,6 +318,7 @@ solve( const Vector& b, Vector& x )
       /****
        * r = M.solve(b - A * x);
        */
+      const RealType beta_old = beta;
       beta = 0.0;
       if( preconditioner )
       {
@@ -292,6 +339,9 @@ solve( const Vector& b, Vector& x )
       //cout << " beta = " << beta << std::endl;
       //cout << "residue = " << beta / normb << std::endl;
 
+      // update parameters for the adaptivity of the restarting parameter
+      ++restart_cycles;
+      beta_ratio = beta / beta_old;
    }
    this->refreshSolverMonitor( true );
    return this->checkConvergence();
@@ -378,26 +428,22 @@ applyPlaneRotation( RealType& dx,
 
 template< typename Matrix,
           typename Preconditioner >
-bool
+void
 GMRES< Matrix, Preconditioner >::
 setSize( IndexType _size, IndexType m )
 {
-   if( size == _size && restarting == m ) return true;
+   if( size == _size && restarting_max == m )
+      return;
    size = _size;
-   restarting = m;
-   if( ! _r.setSize( size ) ||
-       ! w.setSize( size ) ||
-       ! _s.setSize( restarting + 1 ) ||
-       ! _cs.setSize( restarting + 1 ) ||
-       ! _sn.setSize( restarting + 1 ) ||
-       ! _v.setSize( size * ( restarting + 1 ) ) ||
-       ! _H.setSize( ( restarting + 1 ) * restarting ) ||
-       ! _M_tmp.setSize( size ) )
-   {
-      std::cerr << "I could not allocate all supporting arrays for the GMRES solver." << std::endl;
-      return false;
-   }
-   return true;
+   restarting_max = m;
+   _r.setSize( size );
+   w.setSize( size );
+   _s.setSize( m + 1 );
+   _cs.setSize( m + 1 );
+   _sn.setSize( m + 1 );
+   _v.setSize( size * ( m + 1 ) );
+   _H.setSize( ( m + 1 ) * m );
+   _M_tmp.setSize( size );
 }
 
 } // namespace Linear
diff --git a/src/TNL/Solvers/Linear/LinearResidueGetter_impl.h b/src/TNL/Solvers/Linear/LinearResidueGetter_impl.h
index ccd70971c4a9937043f87a2c3d3005f049098b25..db81e861f7cd850ed151e305eb81c6915def7f4f 100644
--- a/src/TNL/Solvers/Linear/LinearResidueGetter_impl.h
+++ b/src/TNL/Solvers/Linear/LinearResidueGetter_impl.h
@@ -10,6 +10,10 @@
 
 #pragma once
 
+#include <cmath>
+
+#include <TNL/Solvers/Linear/LinearResidueGetter.h>
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {   
diff --git a/src/TNL/Solvers/Linear/Preconditioners/CMakeLists.txt b/src/TNL/Solvers/Linear/Preconditioners/CMakeLists.txt
old mode 100755
new mode 100644
index d14c10ad596625ba7f069f1697ec0737b8622212..43541c7ec74936497212c8436d95a2cbe03c3fcd
--- a/src/TNL/Solvers/Linear/Preconditioners/CMakeLists.txt
+++ b/src/TNL/Solvers/Linear/Preconditioners/CMakeLists.txt
@@ -1,6 +1,8 @@
 SET( headers Dummy.h
              Diagonal.h
              Diagonal_impl.h
+             ILU0.h
+             ILU0_impl.h
    )
    
 INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Solvers/Linear/Preconditioners )
diff --git a/src/TNL/Solvers/Linear/Preconditioners/Diagonal.h b/src/TNL/Solvers/Linear/Preconditioners/Diagonal.h
index 1e4fbe49b00780a572afba8f7d905a7497414628..ecef1953923b3705de08ea5dd3c4d544dc6fd184 100644
--- a/src/TNL/Solvers/Linear/Preconditioners/Diagonal.h
+++ b/src/TNL/Solvers/Linear/Preconditioners/Diagonal.h
@@ -1,3 +1,14 @@
+/***************************************************************************
+                          Diagonal.h  -  description
+                             -------------------
+    begin                : Dec 17, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
 
 #pragma once
 
diff --git a/src/TNL/Solvers/Linear/Preconditioners/Diagonal_impl.h b/src/TNL/Solvers/Linear/Preconditioners/Diagonal_impl.h
index 1033ab29c103b4afdd5bb3518f06689f482184a0..0c77239443c054c4429416c5c654ab53d8419a9e 100644
--- a/src/TNL/Solvers/Linear/Preconditioners/Diagonal_impl.h
+++ b/src/TNL/Solvers/Linear/Preconditioners/Diagonal_impl.h
@@ -1,3 +1,14 @@
+/***************************************************************************
+                          Diagonal_impl.h  -  description
+                             -------------------
+    begin                : Dec 17, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
 
 #pragma once
 
@@ -46,7 +57,8 @@ update( const MatrixPointer& matrix )
 {
 //  std::cout << getType() << "->setMatrix()" << std::endl;
 
-   Assert( matrix->getRows() > 0 && matrix->getRows() == matrix->getColumns(), );
+   TNL_ASSERT_GT( matrix->getRows(), 0, "empty matrix" );
+   TNL_ASSERT_EQ( matrix->getRows(), matrix->getColumns(), "matrix must be square" );
 
    if( diagonal.getSize() != matrix->getRows() )
       diagonal.setSize( matrix->getRows() );
@@ -70,7 +82,7 @@ update( const MatrixPointer& matrix )
             &matrix.template getData< Devices::Cuda >(),
             diagonal.getData(),
             size );
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
 #endif
    }
 }
@@ -101,7 +113,7 @@ solve( const Vector1& b, Vector2& x ) const
             x.getData(),
             size );
 
-      checkCudaDevice;
+      TNL_CHECK_CUDA_DEVICE;
 #endif
    }
    return true;
diff --git a/src/TNL/Solvers/Linear/Preconditioners/Dummy.h b/src/TNL/Solvers/Linear/Preconditioners/Dummy.h
index 291ca7e7568eec277d72ca1aee3ea833ad1394eb..2a7283b22bd31f881b2d8a320b09ddc50b3bbe8a 100644
--- a/src/TNL/Solvers/Linear/Preconditioners/Dummy.h
+++ b/src/TNL/Solvers/Linear/Preconditioners/Dummy.h
@@ -11,6 +11,7 @@
 #pragma once
 
 #include <TNL/Object.h>
+#include <TNL/SharedPointer.h>
 
 namespace TNL {
 namespace Solvers {
@@ -26,7 +27,11 @@ class Dummy
    void update( const Matrix& matrix ) {}
 
    template< typename Vector1, typename Vector2 >
-   bool solve( const Vector1& b, Vector2& x ) const { return true; }
+   bool solve( const Vector1& b, Vector2& x ) const
+   {
+      TNL_ASSERT_TRUE( false, "The solve() method of a dummy preconditioner should not be called." );
+      return true;
+   }
 
    String getType() const
    {
@@ -39,7 +44,8 @@ class SolverStarterSolverPreconditionerSetter
 {
    public:
        
-      static void run( LinearSolver& solver, Preconditioner& preconditioner )
+      static void run( LinearSolver& solver,
+                       SharedPointer< Preconditioner, typename LinearSolver::DeviceType >& preconditioner )
       {
          solver.setPreconditioner( preconditioner );
       }
@@ -53,7 +59,8 @@ class SolverStarterSolverPreconditionerSetter< LinearSolver, Dummy< Real, Device
       typedef Device DeviceType;
       typedef Dummy< Real, DeviceType, Index > PreconditionerType;
    
-      static void run( LinearSolver& solver, PreconditionerType& preconditioner )
+      static void run( LinearSolver& solver,
+                       SharedPointer< PreconditionerType, typename LinearSolver::DeviceType >& preconditioner )
       {
          // do nothing
       }
diff --git a/src/TNL/Solvers/Linear/Preconditioners/ILU0.h b/src/TNL/Solvers/Linear/Preconditioners/ILU0.h
new file mode 100644
index 0000000000000000000000000000000000000000..651f36b73fc3f8773d2063ae7d0dec53f96f82f5
--- /dev/null
+++ b/src/TNL/Solvers/Linear/Preconditioners/ILU0.h
@@ -0,0 +1,206 @@
+/***************************************************************************
+                          ILU0.h  -  description
+                             -------------------
+    begin                : Dec 24, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include <type_traits>
+
+#include <TNL/Object.h>
+#include <TNL/Containers/Vector.h>
+#include <TNL/Matrices/CSR.h>
+
+#ifdef HAVE_CUDA
+#include <cusparse.h>
+#endif
+
+namespace TNL {
+namespace Solvers {
+namespace Linear {
+namespace Preconditioners {
+
+template< typename Real, typename Device, typename Index >
+class ILU0
+{};
+
+template< typename Real, typename Index >
+class ILU0< Real, Devices::Host, Index >
+{
+public:
+   typedef Real RealType;
+   typedef Devices::Host DeviceType;
+   typedef Index IndexType;
+
+   template< typename MatrixPointer >
+   void update( const MatrixPointer& matrixPointer );
+
+   template< typename Vector1, typename Vector2 >
+   bool solve( const Vector1& b, Vector2& x ) const;
+
+   String getType() const
+   {
+      return String( "ILU0" );
+   }
+
+protected:
+//   Matrices::CSR< RealType, DeviceType, IndexType > A;
+   Matrices::CSR< RealType, DeviceType, IndexType > L;
+   Matrices::CSR< RealType, DeviceType, IndexType > U;
+};
+
+template<>
+class ILU0< double, Devices::Cuda, int >
+{
+public:
+   using RealType = double;
+   using DeviceType = Devices::Cuda;
+   using IndexType = int;
+
+   ILU0()
+   {
+#ifdef HAVE_CUDA
+      cusparseCreate( &handle );
+#endif
+   }
+
+   template< typename MatrixPointer >
+   void update( const MatrixPointer& matrixPointer );
+
+   template< typename Vector1, typename Vector2 >
+   bool solve( const Vector1& b, Vector2& x ) const;
+
+   String getType() const
+   {
+      return String( "ILU0" );
+   }
+
+   ~ILU0()
+   {
+#ifdef HAVE_CUDA
+      resetMatrices();
+      cusparseDestroy( handle );
+#endif
+   }
+
+protected:
+#ifdef HAVE_CUDA
+   Matrices::CSR< RealType, DeviceType, IndexType > A;
+   Containers::Vector< RealType, DeviceType, IndexType > y;
+
+   cusparseHandle_t handle;
+
+   cusparseMatDescr_t descr_A = 0;
+   cusparseMatDescr_t descr_L = 0;
+   cusparseMatDescr_t descr_U = 0;
+   csrilu02Info_t     info_A  = 0;
+   csrsv2Info_t       info_L  = 0;
+   csrsv2Info_t       info_U  = 0;
+
+   const cusparseSolvePolicy_t policy_A = CUSPARSE_SOLVE_POLICY_USE_LEVEL;
+   const cusparseSolvePolicy_t policy_L = CUSPARSE_SOLVE_POLICY_USE_LEVEL;
+   const cusparseSolvePolicy_t policy_U = CUSPARSE_SOLVE_POLICY_USE_LEVEL;
+   const cusparseOperation_t trans_L  = CUSPARSE_OPERATION_NON_TRANSPOSE;
+   const cusparseOperation_t trans_U  = CUSPARSE_OPERATION_NON_TRANSPOSE;
+
+   Containers::Array< char, DeviceType, int > pBuffer;
+
+   // scaling factor for triangular solves
+   const double alpha = 1.0;
+
+   void resetMatrices()
+   {
+      if( descr_A ) {
+         cusparseDestroyMatDescr( descr_A );
+         descr_A = 0;
+      }
+      if( descr_L ) {
+         cusparseDestroyMatDescr( descr_L );
+         descr_L = 0;
+      }
+      if( descr_U ) {
+         cusparseDestroyMatDescr( descr_U );
+         descr_U = 0;
+      }
+      if( info_A ) {
+         cusparseDestroyCsrilu02Info( info_A );
+         info_A = 0;
+      }
+      if( info_L ) {
+         cusparseDestroyCsrsv2Info( info_L );
+         info_L = 0;
+      }
+      if( info_U ) {
+         cusparseDestroyCsrsv2Info( info_U );
+         info_U = 0;
+      }
+      pBuffer.reset();
+   }
+
+   // TODO: extend Matrices::copySparseMatrix accordingly
+   template< typename Matrix,
+             typename = typename std::enable_if< ! std::is_same< DeviceType, typename Matrix::DeviceType >::value >::type >
+   void copyMatrix( const Matrix& matrix )
+   {
+      typename Matrix::CudaType A_tmp;
+      A_tmp = matrix;
+      Matrices::copySparseMatrix( A, A_tmp );
+   }
+
+   template< typename Matrix,
+             typename = typename std::enable_if< std::is_same< DeviceType, typename Matrix::DeviceType >::value >::type,
+             typename = void >
+   void copyMatrix( const Matrix& matrix )
+   {
+      Matrices::copySparseMatrix( A, matrix );
+   }
+#endif
+};
+
+#ifdef HAVE_MIC
+template< typename Real, typename Index >
+class ILU0< Real, Devices::MIC, Index >
+{
+public:
+   typedef Real RealType;
+   typedef Devices::MIC DeviceType;
+   typedef Index IndexType;
+
+   template< typename MatrixPointer >
+   void update( const MatrixPointer& matrixPointer )
+   {
+      throw std::runtime_error("Not Iplemented yet for MIC");
+   }
+
+   template< typename Vector1, typename Vector2 >
+   bool solve( const Vector1& b, Vector2& x ) const
+   {
+      throw std::runtime_error("Not Iplemented yet for MIC");
+   }
+
+   String getType() const
+   {
+      return String( "ILU0" );
+   }
+
+protected:
+//   Matrices::CSR< RealType, DeviceType, IndexType > A;
+   Matrices::CSR< RealType, DeviceType, IndexType > L;
+   Matrices::CSR< RealType, DeviceType, IndexType > U;
+};
+
+#endif
+
+} // namespace Preconditioners
+} // namespace Linear
+} // namespace Solvers
+} // namespace TNL
+
+#include <TNL/Solvers/Linear/Preconditioners/ILU0_impl.h>
diff --git a/src/TNL/Solvers/Linear/Preconditioners/ILU0_impl.h b/src/TNL/Solvers/Linear/Preconditioners/ILU0_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..58d1c4ad8c9cee8572e05e83de81105b5a96086f
--- /dev/null
+++ b/src/TNL/Solvers/Linear/Preconditioners/ILU0_impl.h
@@ -0,0 +1,300 @@
+/***************************************************************************
+                          ILU0_impl.h  -  description
+                             -------------------
+    begin                : Dec 24, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
+#pragma once
+
+#include "ILU0.h"
+
+#include <TNL/Exceptions/CudaSupportMissing.h>
+
+namespace TNL {
+namespace Solvers {
+namespace Linear {
+namespace Preconditioners {   
+
+template< typename Real, typename Index >
+   template< typename MatrixPointer >
+void
+ILU0< Real, Devices::Host, Index >::
+update( const MatrixPointer& matrixPointer )
+{
+   TNL_ASSERT_GT( matrixPointer->getRows(), 0, "empty matrix" );
+   TNL_ASSERT_EQ( matrixPointer->getRows(), matrixPointer->getColumns(), "matrix must be square" );
+
+   const IndexType N = matrixPointer->getRows();
+
+   L.setDimensions( N, N );
+   U.setDimensions( N, N );
+
+   // copy row lengths
+   typename decltype(L)::CompressedRowLengthsVector L_rowLengths;
+   typename decltype(U)::CompressedRowLengthsVector U_rowLengths;
+   L_rowLengths.setSize( N );
+   U_rowLengths.setSize( N );
+   for( IndexType i = 0; i < N; i++ ) {
+       const auto row = matrixPointer->getRow( i );
+       const auto max_length = matrixPointer->getRowLength( i );
+       IndexType L_entries = 0;
+       IndexType U_entries = 0;
+       for( IndexType j = 0; j < max_length; j++ ) {
+           const auto column = row.getElementColumn( j );
+           if( column < i )
+               L_entries++;
+           else if( column < N )
+              U_entries++;
+           else
+               break;
+       }
+      L_rowLengths[ i ] = L_entries;
+      U_rowLengths[ N - 1 - i ] = U_entries;
+   }
+   L.setCompressedRowLengths( L_rowLengths );
+   U.setCompressedRowLengths( U_rowLengths );
+
+   // Incomplete LU factorization
+   // The factors L and U are stored separately and the rows of U are reversed.
+   for( IndexType i = 0; i < N; i++ ) {
+      // copy all non-zero entries from A into L and U
+      const auto max_length = matrixPointer->getRowLength( i );
+      IndexType columns[ max_length ];
+      RealType values[ max_length ];
+      matrixPointer->getRowFast( i, columns, values );
+
+      const auto L_entries = L_rowLengths[ i ];
+      const auto U_entries = U_rowLengths[ N - 1 - i ];
+      L.setRow( i, columns, values, L_entries );
+      U.setRow( N - 1 - i, &columns[ L_entries ], &values[ L_entries ], U_entries );
+
+      // this condition is to avoid segfaults on empty L.getRow( i )
+      if( L_entries > 0 ) {
+         const auto L_i = L.getRow( i );
+         const auto U_i = U.getRow( N - 1 - i );
+
+         // loop for k = 0, ..., i - 2; but only over the non-zero entries
+         for( IndexType c_k = 0; c_k < L_entries; c_k++ ) {
+            const auto k = L_i.getElementColumn( c_k );
+
+            auto L_ik = L.getElementFast( i, k ) / U.getElementFast( N - 1 - k, k );
+            L.setElement( i, k, L_ik );
+
+            // loop for j = k+1, ..., N-1; but only over the non-zero entries
+            // and split into two loops over L and U separately
+            for( IndexType c_j = c_k + 1; c_j < L_entries; c_j++ ) {
+               const auto j = L_i.getElementColumn( c_j );
+               const auto L_ij = L.getElementFast( i, j ) - L_ik * U.getElementFast( N - 1 - k, j );
+               L.setElement( i, j, L_ij );
+            }
+            for( IndexType c_j = 0; c_j < U_entries; c_j++ ) {
+               const auto j = U_i.getElementColumn( c_j );
+               const auto U_ij = U.getElementFast( N - 1 - i, j ) - L_ik * U.getElementFast( N - 1 - k, j );
+               U.setElement( N - 1 - i, j, U_ij );
+            }
+         }
+      }
+   }
+}
+
+template< typename Real, typename Index >
+   template< typename Vector1, typename Vector2 >
+bool
+ILU0< Real, Devices::Host, Index >::
+solve( const Vector1& b, Vector2& x ) const
+{
+   TNL_ASSERT_EQ( b.getSize(), L.getRows(), "wrong size of the right hand side" );
+   TNL_ASSERT_EQ( x.getSize(), L.getRows(), "wrong size of the solution vector" );
+
+   const IndexType N = x.getSize();
+
+   // Step 1: solve y from Ly = b
+   for( IndexType i = 0; i < N; i++ ) {
+      x[ i ] = b[ i ];
+
+      const auto L_entries = L.getRowLength( i );
+
+      // this condition is to avoid segfaults on empty L.getRow( i )
+      if( L_entries > 0 ) {
+         const auto L_i = L.getRow( i );
+
+         // loop for j = 0, ..., i - 1; but only over the non-zero entries
+         for( IndexType c_j = 0; c_j < L_entries; c_j++ ) {
+            const auto j = L_i.getElementColumn( c_j );
+            x[ i ] -= L_i.getElementValue( c_j ) * x[ j ];
+         }
+      }
+   }
+
+   // Step 2: solve x from Ux = y
+   for( IndexType i = N - 1; i >= 0; i-- ) {
+      const IndexType U_idx = N - 1 - i;
+
+      const auto U_entries = U.getRowLength( U_idx );
+      const auto U_i = U.getRow( U_idx );
+
+      const auto U_ii = U_i.getElementValue( 0 );
+
+      // loop for j = i+1, ..., N-1; but only over the non-zero entries
+      for( IndexType c_j = 1; c_j < U_entries ; c_j++ ) {
+         const auto j = U_i.getElementColumn( c_j );
+         x[ i ] -= U_i.getElementValue( c_j ) * x[ j ];
+      }
+
+      x[ i ] /= U_ii;
+   }
+
+   return true;
+}
+
+
+   template< typename MatrixPointer >
+void
+ILU0< double, Devices::Cuda, int >::
+update( const MatrixPointer& matrixPointer )
+{
+#ifdef HAVE_CUDA
+   // TODO: only numerical factorization has to be done every time, split the rest into separate "setup" method which is called less often
+   resetMatrices();
+
+   // Note: the decomposition will be in-place, matrices L and U will have the
+   // storage of A
+   copyMatrix( *matrixPointer );
+
+   const int m = A.getRows();
+   const int nnz = A.getValues().getSize();
+
+   y.setSize( m );
+
+   // create matrix descriptors
+   cusparseCreateMatDescr( &descr_A );
+   cusparseSetMatIndexBase( descr_A, CUSPARSE_INDEX_BASE_ZERO );
+   cusparseSetMatType( descr_A, CUSPARSE_MATRIX_TYPE_GENERAL );
+
+   cusparseCreateMatDescr( &descr_L );
+   cusparseSetMatIndexBase( descr_L, CUSPARSE_INDEX_BASE_ZERO );
+   cusparseSetMatType( descr_L, CUSPARSE_MATRIX_TYPE_GENERAL );
+   cusparseSetMatFillMode( descr_L, CUSPARSE_FILL_MODE_LOWER );
+   cusparseSetMatDiagType( descr_L, CUSPARSE_DIAG_TYPE_UNIT );
+
+   cusparseCreateMatDescr( &descr_U);
+   cusparseSetMatIndexBase( descr_U, CUSPARSE_INDEX_BASE_ZERO );
+   cusparseSetMatType( descr_U, CUSPARSE_MATRIX_TYPE_GENERAL );
+   cusparseSetMatFillMode( descr_U, CUSPARSE_FILL_MODE_UPPER );
+   cusparseSetMatDiagType( descr_U, CUSPARSE_DIAG_TYPE_NON_UNIT );
+
+   // create info structures
+   cusparseCreateCsrilu02Info( &info_A );
+   cusparseCreateCsrsv2Info( &info_L );
+   cusparseCreateCsrsv2Info( &info_U );
+
+   // query how much memory will be needed in csrilu02 and csrsv2, and allocate the buffer
+   int pBufferSize_A, pBufferSize_L, pBufferSize_U;
+   cusparseDcsrilu02_bufferSize( handle, m, nnz, descr_A,
+                                 A.getValues().getData(),
+                                 A.getRowPointers().getData(),
+                                 A.getColumnIndexes().getData(),
+                                 info_A, &pBufferSize_A );
+   cusparseDcsrsv2_bufferSize( handle, trans_L, m, nnz, descr_L,
+                               A.getValues().getData(),
+                               A.getRowPointers().getData(),
+                               A.getColumnIndexes().getData(),
+                               info_L, &pBufferSize_L );
+   cusparseDcsrsv2_bufferSize( handle, trans_U, m, nnz, descr_U,
+                               A.getValues().getData(),
+                               A.getRowPointers().getData(),
+                               A.getColumnIndexes().getData(),
+                               info_U, &pBufferSize_U );
+   const int pBufferSize = max( pBufferSize_A, max( pBufferSize_L, pBufferSize_U ) );
+   pBuffer.setSize( pBufferSize );
+
+   // Symbolic analysis of the incomplete LU decomposition
+   cusparseDcsrilu02_analysis( handle, m, nnz, descr_A,
+                               A.getValues().getData(),
+                               A.getRowPointers().getData(),
+                               A.getColumnIndexes().getData(),
+                               info_A, policy_A, pBuffer.getData() );
+   int structural_zero;
+   cusparseStatus_t
+   status = cusparseXcsrilu02_zeroPivot( handle, info_A, &structural_zero );
+   if( CUSPARSE_STATUS_ZERO_PIVOT == status ) {
+      std::cerr << "A(" << structural_zero << ", " << structural_zero << ") is missing." << std::endl;
+      throw 1;
+   }
+
+   // Analysis for the triangular solves for L and U
+   // Trick: the lower (upper) triangular part of A has the same sparsity
+   // pattern as L (U), so we can do the analysis for csrsv2 on the matrix A.
+   cusparseDcsrsv2_analysis( handle, trans_L, m, nnz, descr_L,
+                             A.getValues().getData(),
+                             A.getRowPointers().getData(),
+                             A.getColumnIndexes().getData(),
+                             info_L, policy_L, pBuffer.getData() );
+   cusparseDcsrsv2_analysis( handle, trans_U, m, nnz, descr_U,
+                             A.getValues().getData(),
+                             A.getRowPointers().getData(),
+                             A.getColumnIndexes().getData(),
+                             info_U, policy_U, pBuffer.getData() );
+
+   // Numerical incomplete LU decomposition
+   cusparseDcsrilu02( handle, m, nnz, descr_A,
+                      A.getValues().getData(),
+                      A.getRowPointers().getData(),
+                      A.getColumnIndexes().getData(),
+                      info_A, policy_A, pBuffer.getData() );
+   int numerical_zero;
+   status = cusparseXcsrilu02_zeroPivot( handle, info_A, &numerical_zero );
+   if( CUSPARSE_STATUS_ZERO_PIVOT == status ) {
+      std::cerr << "A(" << numerical_zero << ", " << numerical_zero << ") is zero." << std::endl;
+      throw 1;
+   }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+   template< typename Vector1, typename Vector2 >
+bool
+ILU0< double, Devices::Cuda, int >::
+solve( const Vector1& b, Vector2& x ) const
+{
+#ifdef HAVE_CUDA
+   const int m = A.getRows();
+   const int nnz = A.getValues().getSize();
+
+   // Step 1: solve y from Ly = b
+   cusparseDcsrsv2_solve( handle, trans_L, m, nnz, &alpha, descr_L,
+                          A.getValues().getData(),
+                          A.getRowPointers().getData(),
+                          A.getColumnIndexes().getData(),
+                          info_L,
+                          b.getData(),
+                          (RealType*) y.getData(),
+                          policy_L, (void*) pBuffer.getData() );
+
+   // Step 2: solve x from Ux = y
+   cusparseDcsrsv2_solve( handle, trans_U, m, nnz, &alpha, descr_U,
+                          A.getValues().getData(),
+                          A.getRowPointers().getData(),
+                          A.getColumnIndexes().getData(),
+                          info_U,
+                          y.getData(),
+                          x.getData(),
+                          policy_U, (void*) pBuffer.getData() );
+
+   return true;
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+} // namespace Preconditioners
+} // namespace Linear
+} // namespace Solvers
+} // namespace TNL
diff --git a/src/TNL/Solvers/Linear/SOR.h b/src/TNL/Solvers/Linear/SOR.h
index 2a3528f05c86563f06d18aa705c71b94f0b71bb2..fe36b65932aa0e4eed149a3e1f46a6acc9560c73 100644
--- a/src/TNL/Solvers/Linear/SOR.h
+++ b/src/TNL/Solvers/Linear/SOR.h
@@ -10,7 +10,6 @@
 
 #pragma once
 
-#include <math.h>
 #include <TNL/Object.h>
 #include <TNL/SharedPointer.h>
 #include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
@@ -36,8 +35,8 @@ class SOR : public Object,
    typedef typename Matrix :: DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
    SOR();
 
@@ -61,8 +60,6 @@ class SOR : public Object,
              typename ResidueGetter = LinearResidueGetter< Matrix, Vector >  >
    bool solve( const Vector& b, Vector& x );
 
-   ~SOR();
-
    protected:
 
    RealType omega;
@@ -76,4 +73,3 @@ class SOR : public Object,
 } // namespace TNL
 
 #include <TNL/Solvers/Linear/SOR_impl.h>
-
diff --git a/src/TNL/Solvers/Linear/SOR_impl.cpp b/src/TNL/Solvers/Linear/SOR_impl.cpp
index 294b819bcaa73724f0b289f7914fa7e1e2171084..4f4231e18cb7bb517ef09abfe57213e3fe924eda 100644
--- a/src/TNL/Solvers/Linear/SOR_impl.cpp
+++ b/src/TNL/Solvers/Linear/SOR_impl.cpp
@@ -8,6 +8,8 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
+
 #include <TNL/Solvers/Linear/SOR.h>
 #include <TNL/Matrices/CSR.h>
 #include <TNL/Matrices/Ellpack.h>
@@ -54,4 +56,4 @@ template class SOR< Matrices::Multidiagonal< double, Devices::Cuda, long int > >
 } // namespace Solvers
 } // namespace TNL
 
-
+#endif // #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Solvers/Linear/SOR_impl.h b/src/TNL/Solvers/Linear/SOR_impl.h
index 8b99ea392f6b94790bb0752767025284dc4cdd43..509221475dfc2b69c33198cb361fe51f7542a566 100644
--- a/src/TNL/Solvers/Linear/SOR_impl.h
+++ b/src/TNL/Solvers/Linear/SOR_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Solvers/Linear/SOR.h>
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {   
@@ -18,6 +20,11 @@ template< typename Matrix, typename Preconditioner >
 SOR< Matrix, Preconditioner > :: SOR()
 : omega( 1.0 )
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();   
 }
 
 template< typename Matrix, typename Preconditioner >
@@ -101,6 +108,7 @@ bool SOR< Matrix, Preconditioner > :: solve( const Vector& b, Vector& x )
                                       row,
                                       x,
                                       this->getOmega() );
+      // FIXME: the LinearResidueGetter works only on the host
       this->setResidue( ResidueGetter::getResidue( *matrix, x, b, bNorm ) );
       this->refreshSolverMonitor();
    }
@@ -109,15 +117,13 @@ bool SOR< Matrix, Preconditioner > :: solve( const Vector& b, Vector& x )
    return this->checkConvergence();
 };
 
-template< typename Matrix, typename Preconditioner >
-SOR< Matrix, Preconditioner > :: ~SOR()
-{
-}
-
 } // namespace Linear
 } // namespace Solvers
 } // namespace TNL
 
+
+#ifdef TEMPLATE_EXPLICIT_INSTANTIATION
+
 #include <TNL/Matrices/CSR.h>
 #include <TNL/Matrices/Ellpack.h>
 #include <TNL/Matrices/Multidiagonal.h>
@@ -170,3 +176,5 @@ extern template class SOR< tnlMutliDiagonalMatrix< double, Devices::Cuda, long i
 } // namespace Linear
 } // namespace Solvers
 } // namespace TNL
+
+#endif // #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/TNL/Solvers/Linear/TFQMR.h b/src/TNL/Solvers/Linear/TFQMR.h
index 8e47d7c8316375bea9027fa9abc200bbf13d7e59..abf37d737298e27395c1dbb4015f398582cf17a2 100644
--- a/src/TNL/Solvers/Linear/TFQMR.h
+++ b/src/TNL/Solvers/Linear/TFQMR.h
@@ -14,7 +14,6 @@
 #include <TNL/Object.h>
 #include <TNL/SharedPointer.h>
 #include <TNL/Containers/Vector.h>
-#include <TNL/Containers/SharedVector.h>
 #include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 #include <TNL/Solvers/IterativeSolver.h>
 #include <TNL/Solvers/Linear/LinearResidueGetter.h>
@@ -39,8 +38,8 @@ class TFQMR : public Object,
    typedef typename Matrix::DeviceType DeviceType;
    typedef Matrix MatrixType;
    typedef Preconditioner PreconditionerType;
-   typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-   typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+   typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+   typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
    TFQMR();
 
@@ -56,17 +55,15 @@ class TFQMR : public Object,
 
    void setPreconditioner( const PreconditionerPointer& preconditioner );
 
-   template< typename VectorPointer,
-             typename ResidueGetter = LinearResidueGetter< Matrix, typename VectorPointer::ObjectType >  >
-   bool solve( const VectorPointer& b, VectorPointer& x );
-
-   ~TFQMR();
+   template< typename Vector,
+             typename ResidueGetter = LinearResidueGetter< Matrix, Vector >  >
+   bool solve( const Vector& b, Vector& x );
 
    protected:
 
-   bool setSize( IndexType size );
+   void setSize( IndexType size );
 
-   Containers::Vector< RealType, DeviceType, IndexType >  d, r, w, u, v, r_ast, Au, M_tmp;
+   Containers::Vector< RealType, DeviceType, IndexType > d, r, w, u, v, r_ast, Au, M_tmp;
 
    IndexType size;
 
diff --git a/src/TNL/Solvers/Linear/TFQMR_impl.h b/src/TNL/Solvers/Linear/TFQMR_impl.h
index b04c45d3c7371ff6e6e89280d7f45df9bcbeff9d..7f6546a75caa6fe1dc4c09de47a694b46a4f02df 100644
--- a/src/TNL/Solvers/Linear/TFQMR_impl.h
+++ b/src/TNL/Solvers/Linear/TFQMR_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include "TFQMR.h"
+
 namespace TNL {
 namespace Solvers {
 namespace Linear {
@@ -19,6 +21,11 @@ template< typename Matrix,
 TFQMR< Matrix, Preconditioner > :: TFQMR()
 : size( 0 )
 {
+   /****
+    * Clearing the shared pointer means that there is no
+    * preconditioner set.
+    */
+   this->preconditioner.clear();   
 }
 
 template< typename Matrix,
@@ -69,7 +76,7 @@ template< typename Matrix,
    template< typename Vector, typename ResidueGetter >
 bool TFQMR< Matrix, Preconditioner >::solve( const Vector& b, Vector& x )
 {
-   if( ! this->setSize( matrix -> getRows() ) ) return false;
+   this->setSize( matrix -> getRows() );
 
    RealType tau, theta, eta, rho, alpha, b_norm, w_norm;
 
@@ -164,44 +171,27 @@ bool TFQMR< Matrix, Preconditioner >::solve( const Vector& b, Vector& x )
       this->refreshSolverMonitor();
    }
 
-//   this->matrix->vectorProduct( x, r );
-//   r.addVector( b, 1.0, -1.0 );
-//   this->setResidue( r.lpNorm( 2.0 ) / b_norm );
-
    this->refreshSolverMonitor( true );
    return this->checkConvergence();
-};
-
-template< typename Matrix,
-          typename Preconditioner >
-TFQMR< Matrix, Preconditioner > :: ~TFQMR()
-{
-};
+}
 
 template< typename Matrix,
           typename Preconditioner >
-bool TFQMR< Matrix, Preconditioner > :: setSize( IndexType size )
+void TFQMR< Matrix, Preconditioner > :: setSize( IndexType size )
 {
    if( this->size == size )
-      return true;
+      return;
    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 ) ||
-       ! M_tmp. setSize( size ) )
-   {
-      std::cerr << "I am not able to allocate all supporting vectors for the TFQMR solver." << std::endl;
-      return false;
-   }
-   return true;
-
-};
+   d.setSize( size );
+   r.setSize( size );
+   w.setSize( size );
+   u.setSize( size );
+   v.setSize( size );
+   r_ast.setSize( size );
+   Au.setSize( size );
+   M_tmp.setSize( size );
+}
 
 } // namespace Linear
 } // namespace Solvers
 } // namespace TNL
-
diff --git a/src/TNL/Solvers/Linear/UmfpackWrapper.h b/src/TNL/Solvers/Linear/UmfpackWrapper.h
index 043e46c8d72aa14caa95cc8ebdb9d93171adb6f3..a2519d7c133d1e7bb8dfa3b0f912c93586b841a9 100644
--- a/src/TNL/Solvers/Linear/UmfpackWrapper.h
+++ b/src/TNL/Solvers/Linear/UmfpackWrapper.h
@@ -1,4 +1,14 @@
+/***************************************************************************
+                          UmfpackWrapper.h  -  description
+                             -------------------
+    begin                : Mar 21, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
 
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
 
 #pragma once
 
@@ -9,7 +19,7 @@
 #include <TNL/Object.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Matrices/CSR.h>
-#include <TNL/Solvers/preconditioners/Dummy.h>
+#include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 #include <TNL/Solvers/IterativeSolver.h>
 #include <TNL/Solvers/Linear/LinearResidueGetter.h>
 
@@ -25,16 +35,16 @@ struct is_csr_matrix
 };
 
 template< typename Real, typename Device, typename Index >
-struct is_csr_matrix< CSR< Real, Device, Index > >
+struct is_csr_matrix< Matrices::CSR< Real, Device, Index > >
 {
     static const bool value = true;
 };
 
 
 template< typename Matrix,
-          typename Preconditioner = Dummy< typename Matrix :: RealType,
-                                           typename Matrix :: DeviceType,
-                                           typename Matrix :: IndexType> >
+          typename Preconditioner = Preconditioners::Dummy< typename Matrix :: RealType,
+                                                            typename Matrix :: DeviceType,
+                                                            typename Matrix :: IndexType> >
 class UmfpackWrapper
     : public Object,
       // just to ensure the same interface as other linear solvers
@@ -47,8 +57,8 @@ public:
     typedef typename Matrix :: DeviceType DeviceType;
     typedef Matrix MatrixType;
     typedef Preconditioner PreconditionerType;
-    typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-    typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+    typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+    typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
     UmfpackWrapper()
     {
@@ -88,7 +98,7 @@ public:
 
 
 template< typename Preconditioner >
-class UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >
+class UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >
     : public Object,
       // just to ensure the same interface as other linear solvers
       public IterativeSolver< double, int >
@@ -97,10 +107,10 @@ public:
     typedef double RealType;
     typedef int IndexType;
     typedef Devices::Host DeviceType;
-    typedef CSR< double, Devices::Host, int > MatrixType;
+    typedef Matrices::CSR< double, Devices::Host, int > MatrixType;
     typedef Preconditioner PreconditionerType;
-    typedef SharedPointer< const MatrixType, DeviceType, true > MatrixPointer;
-    typedef SharedPointer< const PreconditionerType, DeviceType, true > PreconditionerPointer;
+    typedef SharedPointer< const MatrixType, DeviceType > MatrixPointer;
+    typedef SharedPointer< const PreconditionerType, DeviceType > PreconditionerPointer;
 
     UmfpackWrapper();
 
@@ -132,5 +142,4 @@ protected:
 
 #include "UmfpackWrapper_impl.h"
 
-
 #endif
diff --git a/src/TNL/Solvers/Linear/UmfpackWrapper_impl.h b/src/TNL/Solvers/Linear/UmfpackWrapper_impl.h
index dcb34521c8872b3a751fc0402ec0762d40d091aa..ebc401d633e9e2792bcff1b16ebcb9bc88646a09 100644
--- a/src/TNL/Solvers/Linear/UmfpackWrapper_impl.h
+++ b/src/TNL/Solvers/Linear/UmfpackWrapper_impl.h
@@ -1,4 +1,14 @@
+/***************************************************************************
+                          UmfpackWrapper_impl.h  -  description
+                             -------------------
+    begin                : Mar 21, 2016
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
 
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
 
 #pragma once
 
@@ -11,13 +21,13 @@ namespace Solvers {
 namespace Linear {   
 
 template< typename Preconditioner >
-UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 UmfpackWrapper()
 {}
 
 template< typename Preconditioner >
 void
-UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
@@ -25,7 +35,7 @@ configSetup( Config::ConfigDescription& config,
 
 template< typename Preconditioner >
 bool
-UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -33,14 +43,14 @@ setup( const Config::ParameterContainer& parameters,
 }
 
 template< typename Preconditioner >
-void UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+void UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 setMatrix( const MatrixPointer& matrix )
 {
     this -> matrix = matrix;
 }
 
 template< typename Preconditioner >
-void UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+void UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 setPreconditioner( const PreconditionerPointer& preconditioner )
 {
     this -> preconditioner = preconditioner;
@@ -49,12 +59,13 @@ setPreconditioner( const PreconditionerPointer& preconditioner )
 
 template< typename Preconditioner >
     template< typename Vector, typename ResidueGetter >
-bool UmfpackWrapper< CSR< double, Devices::Host, int >, Preconditioner >::
+bool UmfpackWrapper< Matrices::CSR< double, Devices::Host, int >, Preconditioner >::
 solve( const Vector& b,
        Vector& x )
 {
-    Assert( matrix->getRows() == matrix->getColumns(), );
-    Assert( matrix->getColumns() == x.getSize() && matrix->getColumns() == b.getSize(), );
+    TNL_ASSERT_EQ( matrix->getRows(), matrix->getColumns(), "matrix must be square" );
+    TNL_ASSERT_EQ( matrix->getColumns(), x.getSize(), "wrong size of the solution vector" );
+    TNL_ASSERT_EQ( matrix->getColumns(), b.getSize(), "wrong size of the right hand side" );
 
     const IndexType size = matrix -> getRows();
 
@@ -77,9 +88,9 @@ solve( const Vector& b,
 
     // symbolic reordering of the sparse matrix
     status = umfpack_di_symbolic( size, size,
-                                  matrix->rowPointers.getData(),
-                                  matrix->columnIndexes.getData(),
-                                  matrix->values.getData(),
+                                  matrix->getRowPointers().getData(),
+                                  matrix->getColumnIndexes().getData(),
+                                  matrix->getValues().getData(),
                                   &Symbolic, Control, Info );
     if( status != UMFPACK_OK ) {
         std::cerr << "error: symbolic reordering failed" << std::endl;
@@ -87,9 +98,9 @@ solve( const Vector& b,
     }
 
     // numeric factorization
-    status = umfpack_di_numeric( matrix->rowPointers.getData(),
-                                 matrix->columnIndexes.getData(),
-                                 matrix->values.getData(),
+    status = umfpack_di_numeric( matrix->getRowPointers().getData(),
+                                 matrix->getColumnIndexes().getData(),
+                                 matrix->getValues().getData(),
                                  Symbolic, &Numeric, Control, Info );
     if( status != UMFPACK_OK ) {
         std::cerr << "error: numeric factorization failed" << std::endl;
@@ -98,9 +109,9 @@ solve( const Vector& b,
 
     // solve with specified right-hand-side
     status = umfpack_di_solve( system_type,
-                               matrix->rowPointers.getData(),
-                               matrix->columnIndexes.getData(),
-                               matrix->values.getData(),
+                               matrix->getRowPointers().getData(),
+                               matrix->getColumnIndexes().getData(),
+                               matrix->getValues().getData(),
                                x.getData(),
                                b.getData(),
                                Numeric, Control, Info );
diff --git a/src/TNL/Solvers/MeshTypeResolver.h b/src/TNL/Solvers/MeshTypeResolver.h
index c0dae65549302b7cfc9b8d110a282c9072aafadc..d24bd8afa89c8d56257dd7d8d38684a7b853e210 100644
--- a/src/TNL/Solvers/MeshTypeResolver.h
+++ b/src/TNL/Solvers/MeshTypeResolver.h
@@ -50,81 +50,81 @@ class MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >
 
    protected:
 
-   static bool resolveMeshDimensions( const Config::ParameterContainer& parameters,
-                                      const List< String >& parsedMeshType );
+   static bool resolveMeshDimension( const Config::ParameterContainer& parameters,
+                                      const Containers::List< String >& parsedMeshType );
 
    // Overload for disabled dimensions
-   template< int MeshDimensions,
-             typename = typename std::enable_if< ! ConfigTagDimensions<ConfigTag,MeshDimensions>::enabled >::type,
+   template< int MeshDimension,
+             typename = typename std::enable_if< ! ConfigTagDimension<ConfigTag,MeshDimension>::enabled >::type,
              typename = void >
    static bool resolveMeshRealType( const Config::ParameterContainer& parameters,
-                                    const List< String >& parsedMeshType );
+                                    const Containers::List< String >& parsedMeshType );
 
    // Overload for enabled dimensions
-   template< int MeshDimensions,
-             typename = typename std::enable_if< ConfigTagDimensions<ConfigTag,MeshDimensions>::enabled >::type >
+   template< int MeshDimension,
+             typename = typename std::enable_if< ConfigTagDimension<ConfigTag,MeshDimension>::enabled >::type >
    static bool resolveMeshRealType( const Config::ParameterContainer& parameters,
-                                    const List< String >& parsedMeshType );
+                                    const Containers::List< String >& parsedMeshType );
 
    // Overload for disabled real types
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename = typename std::enable_if< ! ConfigTagReal<ConfigTag, MeshRealType>::enabled >::type,
              typename = void >
    static bool resolveMeshIndexType( const Config::ParameterContainer& parameters,
-                                     const List< String >& parsedMeshType );
+                                     const Containers::List< String >& parsedMeshType );
 
    // Overload for enabled real types
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename = typename std::enable_if< ConfigTagReal<ConfigTag, MeshRealType>::enabled >::type >
    static bool resolveMeshIndexType( const Config::ParameterContainer& parameters,
-                                     const List< String >& parsedMeshType );
+                                     const Containers::List< String >& parsedMeshType );
 
    // Overload for disabled index types
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename MeshIndexType,
              typename = typename std::enable_if< ! ConfigTagIndex<ConfigTag, MeshIndexType>::enabled >::type,
              typename = void >
    static bool resolveMeshType( const Config::ParameterContainer& parameters,
-                                const List< String >& parsedMeshType );
+                                const Containers::List< String >& parsedMeshType );
 
    // Overload for enabled index types
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename MeshIndexType,
              typename = typename std::enable_if< ConfigTagIndex<ConfigTag, MeshIndexType>::enabled >::type >
    static bool resolveMeshType( const Config::ParameterContainer& parameters,
-                                const List< String >& parsedMeshType );
+                                const Containers::List< String >& parsedMeshType );
 
 
 
-   template< int Dimensions, bool DimensionsSupport, typename MeshTypeResolver >
-    friend class MeshTypeResolverDimensionsSupportChecker;
+   template< int Dimension, bool DimensionSupport, typename MeshTypeResolver >
+    friend class MeshTypeResolverDimensionSupportChecker;
 };
 
-/*template< int Dimensions, bool DimensionsSupport, typename MeshTypeResolver >
-class MeshTypeResolverDimensionsSupportChecker
+/*template< int Dimension, bool DimensionSupport, typename MeshTypeResolver >
+class MeshTypeResolverDimensionSupportChecker
 {
 };
 
-template< int Dimensions, typename MeshTypeResolver >
-class MeshTypeResolverDimensionsSupportChecker< Dimensions, true, MeshTypeResolver >
+template< int Dimension, typename MeshTypeResolver >
+class MeshTypeResolverDimensionSupportChecker< Dimension, true, MeshTypeResolver >
 {
    public:
 
-   static bool checkDimensions( const Config::ParameterContainer& parameters,
-                                const List< String >& parsedMeshType );
+   static bool checkDimension( const Config::ParameterContainer& parameters,
+                                const Containers::List< String >& parsedMeshType );
 };
 
-template< int Dimensions, typename MeshTypeResolver >
-class MeshTypeResolverDimensionsSupportChecker< Dimensions, false, MeshTypeResolver >
+template< int Dimension, typename MeshTypeResolver >
+class MeshTypeResolverDimensionSupportChecker< Dimension, false, MeshTypeResolver >
 {
    public:
 
-   static bool checkDimensions( const Config::ParameterContainer& parameters,
-                                const List< String >& parsedMeshType );
+   static bool checkDimension( const Config::ParameterContainer& parameters,
+                                const Containers::List< String >& parsedMeshType );
 };*/
 
 } // namespace Solvers
diff --git a/src/TNL/Solvers/MeshTypeResolver_impl.h b/src/TNL/Solvers/MeshTypeResolver_impl.h
index 2ef00775bac59eba58b6ecb672c7cf3ba6b17d04..c342c58f34204e5e42f163c637bf60aaed2f2df6 100644
--- a/src/TNL/Solvers/MeshTypeResolver_impl.h
+++ b/src/TNL/Solvers/MeshTypeResolver_impl.h
@@ -58,14 +58,14 @@ bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::ru
       std::cerr << "I am not able to detect the mesh type from the file " << meshFileName << "." << std::endl;
       return EXIT_FAILURE;
    }
-  std::cout << meshType << " detected in " << meshFileName << " file." << std::endl;
-   List< String > parsedMeshType;
+   std::cout << meshType << " detected in " << meshFileName << " file." << std::endl;
+   Containers::List< String > parsedMeshType;
    if( ! parseObjectType( meshType, parsedMeshType ) )
    {
       std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl;
       return false;
    }
-   return resolveMeshDimensions( parameters, parsedMeshType );
+   return resolveMeshDimension( parameters, parsedMeshType );
 }
 
 template< template< typename Real, typename Device, typename Index, typename MeshType, typename ConfigTag, typename SolverStarter > class ProblemSetter,
@@ -73,8 +73,10 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshDimensions( const Config::ParameterContainer& parameters,
-                                                                                                        const List< String >& parsedMeshType )
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshDimension( const Config::ParameterContainer& parameters,
+                       const Containers::List< String >& parsedMeshType )
 {
    int dimensions = atoi( parsedMeshType[ 1 ].getString() );
 
@@ -84,7 +86,7 @@ bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::re
       return resolveMeshRealType< 2 >( parameters, parsedMeshType );
    if( dimensions == 3 )
       return resolveMeshRealType< 3 >( parameters, parsedMeshType );
-   std::cerr << "Dimensions higher than 3 are not supported." << std::endl;
+   std::cerr << "Dimension higher than 3 are not supported." << std::endl;
    return false;
 }
 
@@ -93,11 +95,13 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions, typename, typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshRealType( const Config::ParameterContainer& parameters,
-                                                                                                      const List< String >& parsedMeshType )
+   template< int MeshDimension, typename, typename >
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshRealType( const Config::ParameterContainer& parameters,
+                     const Containers::List< String >& parsedMeshType )
 {
-   std::cerr << "Mesh dimension " << MeshDimensions << " is not supported." << std::endl;
+   std::cerr << "Mesh dimension " << MeshDimension << " is not supported." << std::endl;
    return false;
 }
 
@@ -106,16 +110,18 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions, typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshRealType( const Config::ParameterContainer& parameters,
-                                                                                                      const List< String >& parsedMeshType )
+   template< int MeshDimension, typename >
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshRealType( const Config::ParameterContainer& parameters,
+                     const Containers::List< String >& parsedMeshType )
 {
    if( parsedMeshType[ 2 ] == "float" )
-      return resolveMeshIndexType< MeshDimensions, float >( parameters, parsedMeshType );
+      return resolveMeshIndexType< MeshDimension, float >( parameters, parsedMeshType );
    if( parsedMeshType[ 2 ] == "double" )
-      return resolveMeshIndexType< MeshDimensions, double >( parameters, parsedMeshType );
+      return resolveMeshIndexType< MeshDimension, double >( parameters, parsedMeshType );
    if( parsedMeshType[ 2 ] == "long-double" )
-      return resolveMeshIndexType< MeshDimensions, long double >( parameters, parsedMeshType );
+      return resolveMeshIndexType< MeshDimension, long double >( parameters, parsedMeshType );
    std::cerr << "The type '" << parsedMeshType[ 2 ] << "' is not allowed for real type." << std::endl;
    return false;
 }
@@ -125,11 +131,13 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename, typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshIndexType( const Config::ParameterContainer& parameters,
-                                                                                                        const List< String >& parsedMeshType )
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshIndexType( const Config::ParameterContainer& parameters,
+                      const Containers::List< String >& parsedMeshType )
 {
    std::cerr << "The type '" << parsedMeshType[ 4 ] << "' is not allowed for real type." << std::endl;
    return false;
@@ -140,18 +148,20 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshIndexType( const Config::ParameterContainer& parameters,
-                                                                                                        const List< String >& parsedMeshType )
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshIndexType( const Config::ParameterContainer& parameters,
+                      const Containers::List< String >& parsedMeshType )
 {
    if( parsedMeshType[ 4 ] == "short int" )
-      return resolveMeshType< MeshDimensions, MeshRealType, short int >( parameters, parsedMeshType );
+      return resolveMeshType< MeshDimension, MeshRealType, short int >( parameters, parsedMeshType );
    if( parsedMeshType[ 4 ] == "int" )
-      return resolveMeshType< MeshDimensions, MeshRealType, int >( parameters, parsedMeshType );
+      return resolveMeshType< MeshDimension, MeshRealType, int >( parameters, parsedMeshType );
    if( parsedMeshType[ 4 ] == "long int" )
-      return resolveMeshType< MeshDimensions, MeshRealType, long int >( parameters, parsedMeshType );
+      return resolveMeshType< MeshDimension, MeshRealType, long int >( parameters, parsedMeshType );
    std::cerr << "The type '" << parsedMeshType[ 4 ] << "' is not allowed for indexing type." << std::endl;
    return false;
 }
@@ -161,12 +171,14 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename MeshIndexType,
              typename, typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshType( const Config::ParameterContainer& parameters,
-                                                                                                   const List< String >& parsedMeshType )
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshType( const Config::ParameterContainer& parameters,
+                 const Containers::List< String >& parsedMeshType )
 {
    std::cerr << "The type '" << parsedMeshType[ 4 ] << "' is not allowed for indexing type." << std::endl;
    return false;
@@ -177,16 +189,18 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename ConfigTag >
-   template< int MeshDimensions,
+   template< int MeshDimension,
              typename MeshRealType,
              typename MeshIndexType,
              typename >
-bool MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::resolveMeshType( const Config::ParameterContainer& parameters,
-                                                                                                   const List< String >& parsedMeshType )
+bool
+MeshTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, true >::
+resolveMeshType( const Config::ParameterContainer& parameters,
+                 const Containers::List< String >& parsedMeshType )
 {
    if( parsedMeshType[ 0 ] == "Meshes::Grid" )
    {
-      typedef Meshes::Grid< MeshDimensions, MeshRealType, Device, MeshIndexType > MeshType;
+      typedef Meshes::Grid< MeshDimension, MeshRealType, Device, MeshIndexType > MeshType;
       return MeshResolverTerminator< ProblemSetter, Real, Device, Index, MeshType, ConfigTag >::run( parameters );
    }
    std::cerr << "Unknown mesh type " << parsedMeshType[ 0 ] << "." << std::endl;
diff --git a/src/TNL/Solvers/ODE/CMakeLists.txt b/src/TNL/Solvers/ODE/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/Solvers/ODE/Euler_impl.h b/src/TNL/Solvers/ODE/Euler_impl.h
index 46706cf24c8796ed6e92681cadbfed46fddad102..42f563b11438bce4cc7c625a011e134d59d27c1b 100644
--- a/src/TNL/Solvers/ODE/Euler_impl.h
+++ b/src/TNL/Solvers/ODE/Euler_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Devices/MIC.h>
+
 namespace TNL {
 namespace Solvers {
 namespace ODE {
@@ -27,8 +29,6 @@ template< typename Problem >
 Euler< Problem > :: Euler()
 : cflCondition( 0.0 )
 {
-   //timer.reset();
-   //updateTimer.reset();
 };
 
 template< typename Problem >
@@ -60,13 +60,13 @@ bool Euler< Problem > :: setup( const Config::ParameterContainer& parameters,
 template< typename Problem >
 void Euler< Problem > :: setCFLCondition( const RealType& cfl )
 {
-   this->cflCondition = cfl;
+   this -> cflCondition = cfl;
 }
 
 template< typename Problem >
 const typename Problem :: RealType& Euler< Problem > :: getCFLCondition() const
 {
-   return this->cflCondition;
+   return this -> cflCondition;
 }
 
 template< typename Problem >
@@ -76,11 +76,7 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
     * First setup the supporting meshes k1...k5 and k_tmp.
     */
    //timer.start();
-   if( ! k1->setLike( *u ) )
-   {
-      std::cerr << "I do not have enough memory to allocate a supporting grid for the Euler explicit solver." << std::endl;
-      return false;
-   }
+   k1->setLike( *u );
    k1->setValue( 0.0 );
 
 
@@ -94,7 +90,7 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
    this->resetIterations();
    this->setResidue( this->getConvergenceResidue() + 1.0 );
 
-   this->refreshSolverMonitor();
+   this -> refreshSolverMonitor();
 
    /****
     * Start the main loop
@@ -105,12 +101,12 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
        * Compute the RHS
        */
       //timer.stop();
-      this->problem->getExplicitRHS( time, currentTau, u, k1 );
+      this->problem->getExplicitUpdate( time, currentTau, u, k1 );
       //timer.start();
 
       RealType lastResidue = this->getResidue();
       RealType maxResidue( 0.0 );
-      if( this->cflCondition != 0.0 )
+      if( this -> cflCondition != 0.0 )
       {
          maxResidue = k1->absMax();
          if( currentTau * maxResidue > this->cflCondition )
@@ -120,16 +116,14 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
          }
       }
       RealType newResidue( 0.0 );
-      //updateTimer.start();
       computeNewTimeLevel( u, currentTau, newResidue );
-      //updateTimer.stop();
       this->setResidue( newResidue );
 
       /****
        * 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() )
@@ -138,25 +132,23 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
       /****
        * Compute the new time step.
        */
-      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;
 
-      this->refreshSolverMonitor();
+      this -> refreshSolverMonitor();
 
       /****
        * Check stop conditions.
        */
       if( time >= this->getStopTime() ||
-          ( this->getConvergenceResidue() != 0.0 && this->getResidue() < this->getConvergenceResidue() ) )
+          ( this -> getConvergenceResidue() != 0.0 && this->getResidue() < this -> getConvergenceResidue() ) )
       {
-         this->refreshSolverMonitor();
-         //std::cerr << std::endl << "RHS Timer = " << timer.getRealTime() << std::endl;
-         //std::cerr << std::endl << "Update Timer = " << updateTimer.getRealTime() << std::endl;
+         this -> refreshSolverMonitor();
          return true;
       }
 
-      if( this->cflCondition != 0.0 )
+      if( this -> cflCondition != 0.0 )
       {
          currentTau /= 0.95;
          currentTau = min( currentTau, this->getMaxTau() );
@@ -209,12 +201,38 @@ void Euler< Problem > :: computeNewTimeLevel( DofVectorPointer& u,
                                                                       this->cudaBlockResidue.getData() );
          localResidue += this->cudaBlockResidue.sum();
          cudaThreadSynchronize();
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
       }
 #endif
    }
-   localResidue /= tau * ( RealType ) size;
+   
+   //MIC
+   if( std::is_same< DeviceType, Devices::MIC >::value )
+   {
+
+#ifdef HAVE_MIC
+      Devices::MICHider<RealType> mu;
+      mu.pointer=_u;
+      Devices::MICHider<RealType> mk1;
+      mk1.pointer=_k1;
+    #pragma offload target(mic) in(mu,mk1,size) inout(localResidue)
+    {
+      #pragma omp parallel for reduction(+:localResidue) firstprivate( mu, mk1 )  
+      for( IndexType i = 0; i < size; i ++ )
+      {
+         const RealType add = tau * mk1.pointer[ i ];
+         mu.pointer[ i ] += add;
+         localResidue += std::fabs( add );
+      }
+    }
+#endif
+   }
+
+   
+   
+   localResidue /= tau * ( RealType ) size;   
    MPIAllreduce( localResidue, currentResidue, 1, MPI_SUM, this->solver_comm );
+
 }
 
 #ifdef HAVE_CUDA
@@ -226,7 +244,7 @@ __global__ void updateUEuler( const Index size,
                               RealType* cudaBlockResidue )
 {
    extern __shared__ RealType du[];
-   const Index blockOffset = blockIdx. x * blockDim. x;
+   const Index blockOffset = blockIdx. x * blockDim.x;
    const Index i = blockOffset  + threadIdx. x;
    if( i < size )
       u[ i ] += du[ threadIdx.x ] = tau * k1[ i ];
diff --git a/src/TNL/Solvers/ODE/ExplicitSolver.h b/src/TNL/Solvers/ODE/ExplicitSolver.h
index c988e4092444c659b248df0b77656aae98ec1dc8..4c1743c66471c04fa4707730d9d629e9d02f6f50 100644
--- a/src/TNL/Solvers/ODE/ExplicitSolver.h
+++ b/src/TNL/Solvers/ODE/ExplicitSolver.h
@@ -76,7 +76,7 @@ class ExplicitSolver : public IterativeSolver< typename Problem::RealType,
 
    void setRefreshRate( const IndexType& refreshRate );
 
-   void refreshSolverMonitor();
+   void refreshSolverMonitor( bool force = false );
 
 protected:
  
diff --git a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
index f40e1018cf2ec4722da9f185627e829354b0d4cb..352c5ca2b2fee5a6a93ce641114553e0feb662fa 100644
--- a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
+++ b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
@@ -150,7 +150,7 @@ setTimer( Timer* timer )
 template< class Problem >
 void
 ExplicitSolver< Problem >::
-refreshSolverMonitor()
+refreshSolverMonitor( bool force )
 {
    if( this->solverMonitor )
    {
@@ -159,7 +159,6 @@ refreshSolverMonitor()
       this->solverMonitor->setTimeStep( this->getTau() );
       this->solverMonitor->setTime( this->getTime() );
       this->solverMonitor->setRefreshRate( this->refreshRate );
-      this->solverMonitor->refresh();
    }
 }
 
diff --git a/src/TNL/Solvers/ODE/Merson_impl.h b/src/TNL/Solvers/ODE/Merson_impl.h
index 868bc32b59ce652acd55c7f1c58c39a172478e45..d206087f1cc3d5ba78a888ef916b06f40e76235a 100644
--- a/src/TNL/Solvers/ODE/Merson_impl.h
+++ b/src/TNL/Solvers/ODE/Merson_impl.h
@@ -133,19 +133,20 @@ bool Merson< Problem > :: solve( DofVectorPointer& u )
       std::cerr << "No problem was set for the Merson ODE solver." << std::endl;
       return false;
    }
-   /****
-    * First setup the supporting meshes k1...k5 and kAux.
-    */
-   if( ! k1->setLike( *u ) ||
-       ! k2->setLike( *u ) ||
-       ! k3->setLike( *u ) ||
-       ! k4->setLike( *u ) ||
-       ! k5->setLike( *u ) ||
-       ! kAux->setLike( *u ) )
+   if( this->getTau() == 0.0 )
    {
-      std::cerr << "I do not have enough memory to allocate supporting grids for the Merson explicit solver." << std::endl;
+      std::cerr << "The time step for the Merson ODE solver is zero." << std::endl;
       return false;
    }
+   /****
+    * First setup the supporting meshes k1...k5 and kAux.
+    */
+   k1->setLike( *u );
+   k2->setLike( *u );
+   k3->setLike( *u );
+   k4->setLike( *u );
+   k5->setLike( *u );
+   kAux->setLike( *u );
    k1->setValue( 0.0 );
    k2->setValue( 0.0 );
    k3->setValue( 0.0 );
@@ -170,7 +171,7 @@ bool Merson< Problem > :: solve( DofVectorPointer& u )
    /****
     * Start the main loop
     */
-   while( 1 )
+   while( this->checkNextIteration() )
    {
       /****
        * Compute Runge-Kutta coefficients
@@ -227,10 +228,13 @@ bool Merson< Problem > :: solve( DofVectorPointer& u )
       if( time >= this->getStopTime() ||
           ( this->getConvergenceResidue() != 0.0 && this->getResidue() < this->getConvergenceResidue() ) )
       {
-         this->refreshSolverMonitor();
+         this->refreshSolverMonitor( true );
          return true;
       }
    }
+   this->refreshSolverMonitor( true );
+   return this->checkConvergence();
+
 };
 
 template< typename Problem >
@@ -251,55 +255,46 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
    /****
     * Compute data transfers statistics
     */
-#ifdef HAVE_NOT_CXX11
-   k1->template touch< IndexType >( 4 );
-   k2->template touch< IndexType >( 1 );
-   k3->template touch< IndexType >( 2 );
-   k4->template touch< IndexType >( 1 );
-   kAux->template touch< IndexType >( 4 );
-   u->template touch< IndexType >( 4 );
-#else
    k1->touch( 4 );
    k2->touch( 1 );
    k3->touch( 2 );
    k4->touch( 1 );
    kAux->touch( 4 );
    u->touch( 4 );
-#endif
 
    RealType tau_3 = tau / 3.0;
 
    if( std::is_same< DeviceType, Devices::Host >::value )
    {
-      this->problem->getExplicitRHS( time, tau, u, k1 );
+      this->problem->getExplicitUpdate( time, tau, u, k1 );
 
    #ifdef HAVE_OPENMP
    #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, tau, tau_3 ) if( Devices::Host::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 );
+      this->problem->getExplicitUpdate( time + tau_3, tau, kAux, k2 );
 
    #ifdef HAVE_OPENMP
    #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k2, tau, tau_3 ) if( Devices::Host::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 );
+      this->problem->getExplicitUpdate( time + tau_3, tau, kAux, k3 );
 
    #ifdef HAVE_OPENMP
    #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, tau, tau_3 ) if( Devices::Host::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 );
+      this->problem->getExplicitUpdate( time + 0.5 * tau, tau, kAux, k4 );
 
    #ifdef HAVE_OPENMP
    #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, _k4, tau, tau_3 ) if( Devices::Host::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 ] );
-      this->problem->getExplicitRHS( time + tau, tau, kAux, k5 );
+      this->problem->getExplicitUpdate( time + tau, tau, kAux, k5 );
    }
    if( std::is_same< DeviceType, Devices::Cuda >::value )
    {
@@ -310,7 +305,7 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
       this->cudaBlockResidue.setSize( min( cudaBlocks, Devices::Cuda::getMaxGridSize() ) );
       const IndexType threadsPerGrid = Devices::Cuda::getMaxGridSize() * cudaBlockSize.x;
 
-      this->problem->getExplicitRHS( time, tau, u, k1 );
+      this->problem->getExplicitUpdate( time, tau, u, k1 );
       cudaThreadSynchronize();
 
       for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx ++ )
@@ -320,7 +315,7 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
          computeK2Arg<<< cudaBlocks, cudaBlockSize >>>( currentSize, tau, &_u[ gridOffset ], &_k1[ gridOffset ], &_kAux[ gridOffset ] );
       }
       cudaThreadSynchronize();
-      this->problem->getExplicitRHS( time + tau_3, tau, kAux, k2 );
+      this->problem->getExplicitUpdate( time + tau_3, tau, kAux, k2 );
       cudaThreadSynchronize();
 
       for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx ++ )
@@ -330,7 +325,7 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
          computeK3Arg<<< cudaBlocks, cudaBlockSize >>>( currentSize, tau, &_u[ gridOffset ], &_k1[ gridOffset ], &_k2[ gridOffset ], &_kAux[ gridOffset ] );
       }
       cudaThreadSynchronize();
-      this->problem->getExplicitRHS( time + tau_3, tau, kAux, k3 );
+      this->problem->getExplicitUpdate( time + tau_3, tau, kAux, k3 );
       cudaThreadSynchronize();
 
       for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx ++ )
@@ -340,7 +335,7 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
          computeK4Arg<<< cudaBlocks, cudaBlockSize >>>( currentSize, tau, &_u[ gridOffset ], &_k1[ gridOffset ], &_k3[ gridOffset ], &_kAux[ gridOffset ] );
       }
       cudaThreadSynchronize();
-      this->problem->getExplicitRHS( time + 0.5 * tau, tau, kAux, k4 );
+      this->problem->getExplicitUpdate( time + 0.5 * tau, tau, kAux, k4 );
       cudaThreadSynchronize();
 
       for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx ++ )
@@ -350,7 +345,7 @@ void Merson< Problem >::computeKFunctions( DofVectorPointer& u,
          computeK5Arg<<< cudaBlocks, cudaBlockSize >>>( currentSize, tau, &_u[ gridOffset ], &_k1[ gridOffset ], &_k3[ gridOffset ], &_k4[ gridOffset ], &_kAux[ gridOffset ] );
       }
       cudaThreadSynchronize();
-      this->problem->getExplicitRHS( time + tau, tau, kAux, k5 );
+      this->problem->getExplicitUpdate( time + tau, tau, kAux, k5 );
       cudaThreadSynchronize();
 #endif
    }
@@ -369,17 +364,10 @@ typename Problem :: RealType Merson< Problem > :: computeError( const RealType t
    /****
     * Compute data transfers statistics
     */
-#ifdef HAVE_NOT_CXX11
-   k1->template touch< IndexType >();
-   k3->template touch< IndexType >();
-   k4->template touch< IndexType >();
-   k5->template touch< IndexType >();
-#else
    k1->touch();
    k3->touch();
    k4->touch();
    k5->touch();
-#endif
 
    RealType eps( 0.0 ), maxEps( 0.0 );
    if( std::is_same< DeviceType, Devices::Host >::value )
@@ -450,17 +438,10 @@ void Merson< Problem >::computeNewTimeLevel( DofVectorPointer& u,
    /****
     * Compute data transfers statistics
     */
-#ifdef HAVE_NOT_CXX11
-   u->template touch< IndexType >();
-   k1->template touch< IndexType >();
-   k4->template touch< IndexType >();
-   k5->template touch< IndexType >();
-#else
    u->touch();
    k1->touch();
    k4->touch();
    k5->touch();
-#endif
 
    if( std::is_same< DeviceType, Devices::Host >::value )
    {
diff --git a/src/TNL/Solvers/PDE/CMakeLists.txt b/src/TNL/Solvers/PDE/CMakeLists.txt
old mode 100755
new mode 100644
index 0f98d12a9f92b80279e810041ec9e4ba42f7bfaa..346e2acab6284faf682c3dfa53212ef2d5f1864d
--- a/src/TNL/Solvers/PDE/CMakeLists.txt
+++ b/src/TNL/Solvers/PDE/CMakeLists.txt
@@ -3,12 +3,12 @@ SET( headers BackwardTimeDiscretisation.h
              ExplicitTimeStepper.h
              ExplicitTimeStepper_impl.h
              ExplicitUpdater.h
-             ExplicitUpdater_impl.h
              LinearSystemAssembler.h
-             LinearSystemAssembler_impl.h
              NoTimeDiscretisation.h
-             PDESolver.h
-             PDESolver_impl.h
+             TimeDependentPDESolver.h
+             TimeDependentPDESolver_impl.h
+             TimeIndependentPDESolver.h
+             TimeIndependentPDESolver_impl.h
              SemiImplicitTimeStepper.h
              SemiImplicitTimeStepper_impl.h )
 
diff --git a/src/TNL/Solvers/PDE/ExplicitTimeStepper.h b/src/TNL/Solvers/PDE/ExplicitTimeStepper.h
index e51290d05efd5ffd63dd516b3e765c50da524501..381803f2f9d2d8a2bfed04b3022a2bb5898fbb05 100644
--- a/src/TNL/Solvers/PDE/ExplicitTimeStepper.h
+++ b/src/TNL/Solvers/PDE/ExplicitTimeStepper.h
@@ -68,7 +68,7 @@ class ExplicitTimeStepper
                DofVectorPointer& dofVector,
                MeshDependentDataPointer& meshDependentData );
 
-   void getExplicitRHS( const RealType& time,
+   void getExplicitUpdate( const RealType& time,
                         const RealType& tau,
                         DofVectorPointer& _u,
                         DofVectorPointer& _fu );
diff --git a/src/TNL/Solvers/PDE/ExplicitTimeStepper_impl.h b/src/TNL/Solvers/PDE/ExplicitTimeStepper_impl.h
index ea6973f7ba98a77e7d0ac31464c8fd634ce741fb..a2450e38d2acdd331da85a59ef3ca639c022660d 100644
--- a/src/TNL/Solvers/PDE/ExplicitTimeStepper_impl.h
+++ b/src/TNL/Solvers/PDE/ExplicitTimeStepper_impl.h
@@ -122,7 +122,7 @@ solve( const RealType& time,
        DofVectorPointer& dofVector,
        MeshDependentDataPointer& meshDependentData )
 {
-   Assert( this->odeSolver, );
+   TNL_ASSERT_TRUE( this->odeSolver, "ODE solver was not set" );
    mainTimer.start();
    this->odeSolver->setTau( this->timeStep );
    this->odeSolver->setProblem( * this );
@@ -144,7 +144,7 @@ template< typename Problem,
           template < typename OdeProblem > class OdeSolver >
 void
 ExplicitTimeStepper< Problem, OdeSolver >::
-getExplicitRHS( const RealType& time,
+getExplicitUpdate( const RealType& time,
                 const RealType& tau,
                 DofVectorPointer& u,
                 DofVectorPointer& fu )
@@ -172,7 +172,7 @@ getExplicitRHS( const RealType& time,
 
    this->explicitUpdaterTimer.start();
    this->problem->setExplicitBoundaryConditions( time, *this->mesh, u, *this->meshDependentData );
-   this->problem->getExplicitRHS( time, tau, *this->mesh, u, fu, *this->meshDependentData );
+   this->problem->getExplicitUpdate( time, tau, *this->mesh, u, fu, *this->meshDependentData );
    this->explicitUpdaterTimer.stop();
 
    if( this->solverMonitor )
diff --git a/src/TNL/Solvers/PDE/ExplicitUpdater.h b/src/TNL/Solvers/PDE/ExplicitUpdater.h
index b6579d606607462cee6efd5f98d2acc8b2e6666a..264ecef7c0a83a3f6ead920de11a0225fb61cd36 100644
--- a/src/TNL/Solvers/PDE/ExplicitUpdater.h
+++ b/src/TNL/Solvers/PDE/ExplicitUpdater.h
@@ -13,6 +13,12 @@
 #include <TNL/Functions/FunctionAdapter.h>
 #include <TNL/Timer.h>
 #include <TNL/SharedPointer.h>
+#include <type_traits>
+#include <TNL/Meshes/GridDetails/Traverser_Grid1D.h>
+#include <TNL/Meshes/GridDetails/Traverser_Grid2D.h>
+#include <TNL/Meshes/GridDetails/Traverser_Grid3D.h>
+#include <TNL/Solvers/PDE/ExplicitUpdater.h>
+
 
 namespace TNL {
 namespace Solvers {
@@ -47,7 +53,7 @@ class ExplicitUpdaterTraverserUserData
       {}
       
       
-      void setUserData( const Real& time,
+      /*void setUserData( const Real& time,
                         const DifferentialOperator* differentialOperator,
                         const BoundaryConditions* boundaryConditions,
                         const RightHandSide* rightHandSide,
@@ -60,7 +66,7 @@ class ExplicitUpdaterTraverserUserData
          this->rightHandSide = rightHandSide;
          this->u = u;
          this->fu = fu;
-      }
+      }*/
 };
 
 
@@ -78,24 +84,67 @@ class ExplicitUpdater
       typedef typename MeshFunction::DeviceType DeviceType;
       typedef typename MeshFunction::IndexType IndexType;
       typedef ExplicitUpdaterTraverserUserData< RealType,
-                                                   MeshFunction,
-                                                   DifferentialOperator,
-                                                   BoundaryConditions,
-                                                   RightHandSide > TraverserUserData;
+                                                MeshFunction,
+                                                DifferentialOperator,
+                                                BoundaryConditions,
+                                                RightHandSide > TraverserUserData;
       typedef SharedPointer< DifferentialOperator, DeviceType > DifferentialOperatorPointer;
       typedef SharedPointer< BoundaryConditions, DeviceType > BoundaryConditionsPointer;
       typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
       typedef SharedPointer< MeshFunction, DeviceType > MeshFunctionPointer;
       typedef SharedPointer< TraverserUserData, DeviceType > TraverserUserDataPointer;
       
+      void setDifferentialOperator( const DifferentialOperatorPointer& differentialOperatorPointer )
+      {
+         this->userDataPointer->differentialOperator = &differentialOperatorPointer.template getData< DeviceType >();
+      }
+      
+      void setBoundaryConditions( const BoundaryConditionsPointer& boundaryConditionsPointer )
+      {
+         this->userDataPointer->boundaryConditions = &boundaryConditionsPointer.template getData< DeviceType >();
+      }
+      
+      void setRightHandSide( const RightHandSidePointer& rightHandSidePointer )
+      {
+         this->userDataPointer->rightHandSide = &rightHandSidePointer.template getData< DeviceType >();
+      }
+            
       template< typename EntityType >
       void update( const RealType& time,
+                   const RealType& tau,
                    const MeshPointer& meshPointer,
-                   const DifferentialOperatorPointer& differentialOperatorPointer,
-                   const BoundaryConditionsPointer& boundaryConditionsPointer,
-                   const RightHandSidePointer& rightHandSidePointer,
                    MeshFunctionPointer& uPointer,
-                   MeshFunctionPointer& fuPointer );
+                   MeshFunctionPointer& fuPointer )
+      {
+         static_assert( std::is_same< MeshFunction,
+                                      Containers::Vector< typename MeshFunction::RealType,
+                                                 typename MeshFunction::DeviceType,
+                                                 typename MeshFunction::IndexType > >::value != true,
+            "Error: I am getting Vector instead of MeshFunction or similar object. You might forget to bind DofVector into MeshFunction in you method getExplicitUpdate."  );
+            
+         TNL_ASSERT_TRUE( this->userDataPointer->differentialOperator,
+                          "The differential operator is not correctly set-up. Use method setDifferentialOperator() to do it." );
+         TNL_ASSERT_TRUE( this->userDataPointer->boundaryConditions, 
+                          "The boundary conditions are not correctly set-up. Use method setBoundaryCondtions() to do it." );
+         TNL_ASSERT_TRUE( this->userDataPointer->rightHandSide, 
+                          "The right-hand side is not correctly set-up. Use method setRightHandSide() to do it." );
+         
+         
+         this->userDataPointer->time = time;
+         this->userDataPointer->u = &uPointer.template modifyData< DeviceType >();
+         this->userDataPointer->fu = &fuPointer.template modifyData< DeviceType >();
+         Meshes::Traverser< MeshType, EntityType > meshTraverser;
+         meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                         TraverserInteriorEntitiesProcessor >
+                                                       ( meshPointer,
+                                                         userDataPointer );
+         this->userDataPointer->time = time + tau;
+         meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                             TraverserBoundaryEntitiesProcessor >
+                                           ( meshPointer,
+                                             userDataPointer );
+         
+      }
       
          
       class TraverserBoundaryEntitiesProcessor
@@ -118,7 +167,7 @@ class ExplicitUpdater
       {
          public:
 
-            typedef typename MeshType::VertexType VertexType;
+            typedef typename MeshType::PointType PointType;
 
             template< typename EntityType >
             __cuda_callable__
@@ -126,12 +175,23 @@ class ExplicitUpdater
                                               TraverserUserData& userData,
                                               const EntityType& entity )
             {
-               ( *userData.fu )( entity ) =                
-                  ( *userData.differentialOperator )( *userData.u, entity, userData.time );
-
+           /*    std::cerr<<"===========================================================" << std::endl; 
+               std::cerr<<"fu:" << userData.fu << std::endl; 
+               std::cerr<< "diffOp:" << userData.differentialOperator << std::endl; 
+               std::cerr<<"===========================================================" << std::endl; 
+               
+               std::cerr<<std::flush;*/
+               
+            //   int blabla;
+             //  std::cin >> blabla; 
+               
+               ( *userData.fu )( entity ) = 
+                       ( *userData.differentialOperator )( *userData.u, entity, userData.time );
+            
                typedef Functions::FunctionAdapter< MeshType, RightHandSide > FunctionAdapter;
                (  *userData.fu )( entity ) += 
                   FunctionAdapter::getValue( *userData.rightHandSide, entity, userData.time );
+               
             }
       }; 
 
@@ -145,5 +205,3 @@ class ExplicitUpdater
 } // namespace Solvers
 } // namespace TNL
 
-#include <TNL/Solvers/PDE/ExplicitUpdater_impl.h>
-
diff --git a/src/TNL/Solvers/PDE/ExplicitUpdater_impl.h b/src/TNL/Solvers/PDE/ExplicitUpdater_impl.h
deleted file mode 100644
index 02348de740711107376e705c307c2b4c49dd86eb..0000000000000000000000000000000000000000
--- a/src/TNL/Solvers/PDE/ExplicitUpdater_impl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
-                          ExplicitUpdater_impl.h  -  description
-                             -------------------
-    begin                : Jul 29, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <type_traits>
-#include <TNL/Meshes/GridDetails/Traverser_Grid1D.h>
-#include <TNL/Meshes/GridDetails/Traverser_Grid2D.h>
-#include <TNL/Meshes/GridDetails/Traverser_Grid3D.h>
-
-#include <TNL/Solvers/PDE/ExplicitUpdater.h>
-
-
-namespace TNL {
-namespace Solvers {
-namespace PDE {   
-
-template< typename Mesh,
-          typename MeshFunction,
-          typename DifferentialOperator,
-          typename BoundaryConditions,
-          typename RightHandSide >
-   template< typename EntityType >
-void
-ExplicitUpdater< Mesh, MeshFunction, DifferentialOperator, BoundaryConditions, RightHandSide >::
-update( const RealType& time,
-        const MeshPointer& meshPointer,
-        const DifferentialOperatorPointer& differentialOperatorPointer,        
-        const BoundaryConditionsPointer& boundaryConditionsPointer,
-        const RightHandSidePointer& rightHandSidePointer,
-        MeshFunctionPointer& uPointer,
-        MeshFunctionPointer& fuPointer )
-{
-   static_assert( std::is_same< MeshFunction,
-                                Containers::Vector< typename MeshFunction::RealType,
-                                           typename MeshFunction::DeviceType,
-                                           typename MeshFunction::IndexType > >::value != true,
-      "Error: I am getting Vector instead of MeshFunction or similar object. You might forget to bind DofVector into MeshFunction in you method getExplicitRHS."  );
-   {
-      //SharedPointer< TraverserUserData, DeviceType >
-      this->userDataPointer->setUserData( time,
-                                          &differentialOperatorPointer.template getData< DeviceType >(),
-                                          &boundaryConditionsPointer.template getData< DeviceType >(),
-                                          &rightHandSidePointer.template getData< DeviceType >(),
-                                          &uPointer.template modifyData< DeviceType >(),
-                                          &fuPointer.template modifyData< DeviceType >() );
-      Meshes::Traverser< MeshType, EntityType > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserBoundaryEntitiesProcessor >
-                                                    ( meshPointer,
-                                                      userDataPointer );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserInteriorEntitiesProcessor >
-                                                    ( meshPointer,
-                                                      userDataPointer );
-   }
-}
-
-} // namespace PDE
-} // namespace Solvers
-} // namespace TNL
diff --git a/src/TNL/Solvers/PDE/LinearSystemAssembler.h b/src/TNL/Solvers/PDE/LinearSystemAssembler.h
index 42efd0e346f9f3b7d185dc527e9cf743d29c5f0a..d97dd15ef530ec33833d016d4ed321a83d711df6 100644
--- a/src/TNL/Solvers/PDE/LinearSystemAssembler.h
+++ b/src/TNL/Solvers/PDE/LinearSystemAssembler.h
@@ -22,7 +22,6 @@ template< typename Real,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide,
-          typename Matrix,
           typename DofVector >
 class LinearSystemAssemblerTraverserUserData
 {
@@ -41,26 +40,18 @@ class LinearSystemAssemblerTraverserUserData
       
       DofVector* b = NULL;
 
-      Matrix* matrix = NULL;
-
-      void setUserData( const Real& time,
-                        const Real& tau,
-                        const DifferentialOperator* differentialOperator,
-                        const BoundaryConditions* boundaryConditions,
-                        const RightHandSide* rightHandSide,
-                        const MeshFunction* u,
-                        Matrix* matrix,
-                        DofVector* b )
-      {
-         this->time = time;
-         this->tau = tau;
-         this->differentialOperator = differentialOperator;
-         this->boundaryConditions = boundaryConditions;
-         this->rightHandSide = rightHandSide;
-         this->u = u;
-         this->b = b;
-         this->matrix = matrix;
-      }
+      void* matrix = NULL;
+      
+      LinearSystemAssemblerTraverserUserData()
+      : time( 0.0 ),
+        tau( 0.0 ),
+        differentialOperator( NULL ),
+        boundaryConditions( NULL ),
+        rightHandSide( NULL ),
+        u( NULL ),
+        b( NULL ),
+        matrix( NULL )
+      {}
 };
 
 
@@ -70,7 +61,6 @@ template< typename Mesh,
           typename BoundaryConditions,
           typename RightHandSide,
           typename TimeDiscretisation,
-          typename Matrix,
           typename DofVector >
 class LinearSystemAssembler
 {
@@ -80,36 +70,70 @@ class LinearSystemAssembler
    typedef typename MeshFunction::RealType RealType;
    typedef typename MeshFunction::DeviceType DeviceType;
    typedef typename MeshFunction::IndexType IndexType;
-   typedef Matrix MatrixType;
    typedef LinearSystemAssemblerTraverserUserData< RealType,
-                                                      MeshFunction,
-                                                      DifferentialOperator,
-                                                      BoundaryConditions,
-                                                      RightHandSide,
-                                                      MatrixType,
-                                                      DofVector > TraverserUserData;
-
-   typedef SharedPointer< Matrix, DeviceType > MatrixPointer;
+                                                   MeshFunction,
+                                                   DifferentialOperator,
+                                                   BoundaryConditions,
+                                                   RightHandSide,
+                                                   DofVector > TraverserUserData;
+
+   //typedef SharedPointer< Matrix, DeviceType > MatrixPointer;
    typedef SharedPointer< DifferentialOperator, DeviceType > DifferentialOperatorPointer;
    typedef SharedPointer< BoundaryConditions, DeviceType > BoundaryConditionsPointer;
    typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer;
    typedef SharedPointer< MeshFunction, DeviceType > MeshFunctionPointer;
    typedef SharedPointer< DofVector, DeviceType > DofVectorPointer;
    
-      
-   template< typename EntityType >
+   void setDifferentialOperator( const DifferentialOperatorPointer& differentialOperatorPointer )
+   {
+      this->userDataPointer->differentialOperator = &differentialOperatorPointer.template getData< DeviceType >();
+   }
+
+   void setBoundaryConditions( const BoundaryConditionsPointer& boundaryConditionsPointer )
+   {
+      this->userDataPointer->boundaryConditions = &boundaryConditionsPointer.template getData< DeviceType >();
+   }
+
+   void setRightHandSide( const RightHandSidePointer& rightHandSidePointer )
+   {
+      this->userDataPointer->rightHandSide = &rightHandSidePointer.template getData< DeviceType >();
+   }
+   
+   template< typename EntityType, typename Matrix >
    void assembly( const RealType& time,
                   const RealType& tau,
                   const MeshPointer& meshPointer,
-                  const DifferentialOperatorPointer& differentialOperatorPointer,
-                  const BoundaryConditionsPointer& boundaryConditionsPointer,
-                  const RightHandSidePointer& rightHandSidePointer,
                   const MeshFunctionPointer& uPointer,
-                  MatrixPointer& matrixPointer,
-                  DofVectorPointer& bPointer );
+                  SharedPointer< Matrix >& matrixPointer,
+                  DofVectorPointer& bPointer )
+   {
+      static_assert( std::is_same< MeshFunction,
+                                Containers::Vector< typename MeshFunction::RealType,
+                                           typename MeshFunction::DeviceType,
+                                           typename MeshFunction::IndexType > >::value != true,
+      "Error: I am getting Vector instead of MeshFunction or similar object. You might forget to bind DofVector into MeshFunction in you method getExplicitUpdate."  );
+
+      const IndexType maxRowLength = matrixPointer.template getData< Devices::Host >().getMaxRowLength();
+      TNL_ASSERT_GT( maxRowLength, 0, "maximum row length must be positive" );
+      this->userDataPointer->time = time;
+      this->userDataPointer->tau = tau;
+      this->userDataPointer->u = &uPointer.template getData< DeviceType >();
+      this->userDataPointer->matrix = ( void* ) &matrixPointer.template modifyData< DeviceType >();
+      this->userDataPointer->b = &bPointer.template modifyData< DeviceType >();
+      Meshes::Traverser< MeshType, EntityType > meshTraverser;
+      meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                      TraverserBoundaryEntitiesProcessor< Matrix> >
+                                                    ( meshPointer,
+                                                      userDataPointer );
+      meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                      TraverserInteriorEntitiesProcessor< Matrix > >
+                                                    ( meshPointer,
+                                                      userDataPointer );
+      
+   }
 
- 
-      class TraverserBoundaryEntitiesProcessor
+   template< typename Matrix >
+   class TraverserBoundaryEntitiesProcessor
    {
       public:
  
@@ -125,11 +149,12 @@ class LinearSystemAssembler
                  entity,
                  userData.time + userData.tau,
                  userData.tau,
-                 ( *userData.matrix ),
+                 ( * ( Matrix* ) ( userData.matrix ) ),
                  ( *userData.b ) );
          }
    };
 
+   template< typename Matrix >
    class TraverserInteriorEntitiesProcessor
    {
       public:
@@ -146,7 +171,7 @@ class LinearSystemAssembler
                  entity,
                  userData.time + userData.tau,
                  userData.tau,
-                 ( *userData.matrix ),
+                 ( *( Matrix* )( userData.matrix ) ),
                  ( *userData.b ) );
  
             typedef Functions::FunctionAdapter< MeshType, RightHandSide > RhsFunctionAdapter;
@@ -155,7 +180,7 @@ class LinearSystemAssembler
                ( ( *userData.rightHandSide ),
                  entity,
                  userData.time );
-            TimeDiscretisation::applyTimeDiscretisation( ( *userData.matrix ),
+            TimeDiscretisation::applyTimeDiscretisation( ( *( Matrix* )( userData.matrix ) ),
                                                          ( *userData.b )[ entity.getIndex() ],
                                                          entity.getIndex(),
                                                          MeshFunctionAdapter::getValue( ( *userData.u ), entity, userData.time ),
@@ -171,5 +196,3 @@ protected:
 } // namespace PDE
 } // namespace Solvers
 } // namespace TNL
-
-#include <TNL/Solvers/PDE/LinearSystemAssembler_impl.h>
diff --git a/src/TNL/Solvers/PDE/LinearSystemAssembler_impl.h b/src/TNL/Solvers/PDE/LinearSystemAssembler_impl.h
deleted file mode 100644
index 3692920a6544f171d3d60b583adf2b9513e03a74..0000000000000000000000000000000000000000
--- a/src/TNL/Solvers/PDE/LinearSystemAssembler_impl.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
-                          LinearSystemAssembler_impl.h  -  description
-                             -------------------
-    begin                : Oct 12, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <type_traits>
-#include <TNL/Meshes/GridDetails/Traverser_Grid1D.h>
-#include <TNL/Meshes/GridDetails/Traverser_Grid2D.h>
-#include <TNL/Meshes/GridDetails/Traverser_Grid3D.h>
-
-namespace TNL {
-namespace Solvers {
-namespace PDE {   
-
-template< typename Mesh,
-          typename MeshFunction,
-          typename DifferentialOperator,
-          typename BoundaryConditions,
-          typename RightHandSide,
-          typename TimeDiscretisation,
-          typename Matrix,
-          typename DofVector >
-   template< typename EntityType >
-void
-LinearSystemAssembler< Mesh, MeshFunction, DifferentialOperator, BoundaryConditions, RightHandSide, TimeDiscretisation, Matrix, DofVector >::
-assembly( const RealType& time,
-          const RealType& tau,
-          const MeshPointer& meshPointer,
-          const DifferentialOperatorPointer& differentialOperatorPointer,
-          const BoundaryConditionsPointer& boundaryConditionsPointer,
-          const RightHandSidePointer& rightHandSidePointer,
-          const MeshFunctionPointer& uPointer,
-          MatrixPointer& matrixPointer,
-          DofVectorPointer& bPointer )
-{
-      static_assert( std::is_same< MeshFunction,
-                                Containers::Vector< typename MeshFunction::RealType,
-                                           typename MeshFunction::DeviceType,
-                                           typename MeshFunction::IndexType > >::value != true,
-      "Error: I am getting Vector instead of MeshFunction or similar object. You might forget to bind DofVector into MeshFunction in you method getExplicitRHS."  );
-
-   const IndexType maxRowLength = matrixPointer.template getData< Devices::Host >().getMaxRowLength();
-   Assert( maxRowLength > 0, );
-
-   {
-      this->userDataPointer->setUserData(
-            time,
-            tau,
-            &differentialOperatorPointer.template getData< DeviceType >(),
-            &boundaryConditionsPointer.template getData< DeviceType >(),
-            &rightHandSidePointer.template getData< DeviceType >(),
-            &uPointer.template getData< DeviceType >(),
-            &matrixPointer.template modifyData< DeviceType >(),
-            &bPointer.template modifyData< DeviceType >() );
-      Meshes::Traverser< MeshType, EntityType > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserBoundaryEntitiesProcessor >
-                                                    ( meshPointer,
-                                                      userDataPointer );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserInteriorEntitiesProcessor >
-                                                    ( meshPointer,
-                                                      userDataPointer );
-   }
-}
-
-} // namespace PDE
-} // namespace Solvers
-} // namespace TNL
diff --git a/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h b/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h
index b0277034d19db2f98ec4976cdffe8259e0ea5bcd..1c324f8f944d43ae73cea4036ae252768112bc32 100644
--- a/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h
+++ b/src/TNL/Solvers/PDE/SemiImplicitTimeStepper_impl.h
@@ -11,7 +11,8 @@
 #pragma once
 
 #include <TNL/Math.h>
-#include "SemiImplicitTimeStepper.h"
+#include <TNL/Solvers/PDE/SemiImplicitTimeStepper.h>
+#include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 
 namespace TNL {
 namespace Solvers {
@@ -69,8 +70,7 @@ init( const MeshPointer& mesh )
       std::cerr << "Please check the method 'setupLinearSystem' in your solver." << std::endl;
       return false;
    }
-   if( ! this->rightHandSidePointer->setSize( this->matrix.getData().getRows() ) )
-      return false;
+   this->rightHandSidePointer->setSize( this->matrix.getData().getRows() );
 
    this->preIterateTimer.reset();
    this->linearSystemAssemblerTimer.reset();
@@ -154,14 +154,15 @@ solve( const RealType& time,
        DofVectorPointer& dofVector,
        MeshDependentDataPointer& meshDependentData )
 {
-   Assert( this->problem != 0, );
+   TNL_ASSERT_TRUE( this->problem, "problem was not set" );
    RealType t = time;
    this->linearSystemSolver->setMatrix( this->matrix );
    PreconditionerPointer preconditioner;
-   Linear::Preconditioners::SolverStarterSolverPreconditionerSetter< LinearSystemSolverType, PreconditionerPointer >
+   Linear::Preconditioners::SolverStarterSolverPreconditionerSetter< LinearSystemSolverType, PreconditionerType >
        ::run( *(this->linearSystemSolver), preconditioner );
 
-   while( t < stopTime )
+   // ignore very small steps at the end, most likely caused by truncation errors
+   while( stopTime - t > this->timeStep * 1e-6 )
    {
       RealType currentTau = min( this->timeStep, stopTime - t );
 
@@ -207,9 +208,11 @@ solve( const RealType& time,
       this->preconditionerUpdateTimer.stop();
 
       this->linearSystemSolverTimer.start();
-      if( ! this->linearSystemSolver->template solve< DofVectorType, Linear::LinearResidueGetter< MatrixType, DofVectorType > >( *this->rightHandSidePointer, *dofVector ) )
+      if( ! this->linearSystemSolver->solve( *this->rightHandSidePointer, *dofVector ) )
       {
          std::cerr << std::endl << "The linear system solver did not converge." << std::endl;
+         // save the linear system for debugging
+         this->problem->saveFailedLinearSystem( *this->matrix, *dofVector, *this->rightHandSidePointer );
          return false;
       }
       this->linearSystemSolverTimer.stop();
diff --git a/src/TNL/Solvers/PDE/PDESolver.h b/src/TNL/Solvers/PDE/TimeDependentPDESolver.h
similarity index 91%
rename from src/TNL/Solvers/PDE/PDESolver.h
rename to src/TNL/Solvers/PDE/TimeDependentPDESolver.h
index eafbf437076e62296cffae1b97d305a1913a0610..c6a1baa174b64b985e9590372eb913eda784cd47 100644
--- a/src/TNL/Solvers/PDE/PDESolver.h
+++ b/src/TNL/Solvers/PDE/TimeDependentPDESolver.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          PDESolver.h  -  description
+                          TimeDependentPDESolver.h  -  description
                              -------------------
     begin                : Jan 15, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -23,7 +23,7 @@ namespace PDE {
 
 template< typename Problem,
           typename TimeStepper >
-class PDESolver : public Object
+class TimeDependentPDESolver : public Object
 {
    public:
 
@@ -38,7 +38,7 @@ class PDESolver : public Object
       typedef SharedPointer< DofVectorType, DeviceType > DofVectorPointer;
       typedef SharedPointer< MeshDependentDataType, DeviceType > MeshDependentDataPointer;
 
-      PDESolver();
+      TimeDependentPDESolver();
 
       static void configSetup( Config::ConfigDescription& config,
                                const String& prefix = "" );
@@ -87,7 +87,7 @@ class PDESolver : public Object
 
       DofVectorPointer dofsPointer;
 
-      MeshDependentDataPointer meshDependentData;
+      MeshDependentDataPointer meshDependentDataPointer;
 
       TimeStepper* timeStepper;
 
@@ -102,4 +102,4 @@ class PDESolver : public Object
 } // namespace Solvers
 } // namespace TNL
 
-#include <TNL/Solvers/PDE/PDESolver_impl.h>
+#include <TNL/Solvers/PDE/TimeDependentPDESolver_impl.h>
diff --git a/src/TNL/Solvers/PDE/PDESolver_impl.h b/src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h
similarity index 77%
rename from src/TNL/Solvers/PDE/PDESolver_impl.h
rename to src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h
index 5fde1f98be0b041e5e4138e58f79e63674e958a0..6d20972d28c9f06cdf8da05e90567ac50f656e67 100644
--- a/src/TNL/Solvers/PDE/PDESolver_impl.h
+++ b/src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          PDESolver_impl.h  -  description
+                          TimeDependentPDESolver_impl.h  -  description
                              -------------------
     begin                : Jan 15, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include "PDESolver.h"
+#include "TimeDependentPDESolver.h"
 
 namespace TNL {
 namespace Solvers {
@@ -18,8 +18,8 @@ namespace PDE {
 
 template< typename Problem,
           typename TimeStepper >
-PDESolver< Problem, TimeStepper >::
-PDESolver()
+TimeDependentPDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver()
 : timeStepper( 0 ),
   initialTime( 0.0 ),
   finalTime( 0.0 ),
@@ -35,7 +35,7 @@ PDESolver()
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 configSetup( Config::ConfigDescription& config,
              const String& prefix )
 {
@@ -50,7 +50,7 @@ configSetup( Config::ConfigDescription& config,
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setup( const Config::ParameterContainer& parameters,
        const String& prefix )
 {
@@ -71,7 +71,6 @@ setup( const Config::ParameterContainer& parameters,
    /****
     * Setup the problem
     */
-  
    if( ! problem->setup( this->meshPointer, parameters, prefix ) )
    {
       std::cerr << "The problem initiation failed!" << std::endl;
@@ -81,32 +80,25 @@ setup( const Config::ParameterContainer& parameters,
    /****
     * Set DOFs (degrees of freedom)
     */
-   Assert( problem->getDofs( this->meshPointer ) != 0, );
-   std::cout << "Allocating dofs ... ";
-   if( ! this->dofsPointer->setSize( problem->getDofs( this->meshPointer ) ) )
-   {
-      std::cerr << std::endl;
-      std::cerr << "I am not able to allocate DOFs (degrees of freedom)." << std::endl;
-      return false;
-   }
-   std::cout << " [ OK ]" << std::endl;
+   TNL_ASSERT_GT( problem->getDofs( this->meshPointer ), 0, "number of DOFs must be positive" );
+   this->dofsPointer->setSize( problem->getDofs( this->meshPointer ) );
    this->dofsPointer->setValue( 0.0 );
    this->problem->bindDofs( this->meshPointer, this->dofsPointer );
    
    /****
     * Set mesh dependent data
     */
-   this->problem->setMeshDependentData( this->meshPointer, this->meshDependentData );
-   this->problem->bindMeshDependentData( this->meshPointer, this->meshDependentData );
+   this->problem->setMeshDependentData( this->meshPointer, this->meshDependentDataPointer );
+   this->problem->bindMeshDependentData( this->meshPointer, this->meshDependentDataPointer );
    
    /***
     * Set-up the initial condition
     */
-  std::cout << "Setting up the initial condition ... ";
+   std::cout << "Setting up the initial condition ... ";
    typedef typename Problem :: DofVectorType DofVectorType;
-   if( ! this->problem->setInitialCondition( parameters, meshPointer, this->dofsPointer, this->meshDependentData ) )
+   if( ! this->problem->setInitialCondition( parameters, meshPointer, this->dofsPointer, this->meshDependentDataPointer ) )
       return false;
-  std::cout << " [ OK ]" << std::endl;
+   std::cout << " [ OK ]" << std::endl;
 
    /****
     * Initialize the time discretisation
@@ -122,7 +114,7 @@ setup( const Config::ParameterContainer& parameters,
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 writeProlog( Logger& logger,
              const Config::ParameterContainer& parameters )
 {
@@ -142,8 +134,12 @@ writeProlog( Logger& logger,
       logger.writeParameter< double >( "Adaptivity:", "merson-adaptivity", parameters, 1 );
    if( solverName == "sor" )
       logger.writeParameter< double >( "Omega:", "sor-omega", parameters, 1 );
-   if( solverName == "gmres" )
-      logger.writeParameter< int >( "Restarting:", "gmres-restarting", parameters, 1 );
+   if( solverName == "gmres" || solverName == "cwygmres" ) {
+      logger.writeParameter< int >( "Restarting min:", "gmres-restarting-min", parameters, 1 );
+      logger.writeParameter< int >( "Restarting max:", "gmres-restarting-max", parameters, 1 );
+      logger.writeParameter< int >( "Restarting step min:", "gmres-restarting-step-min", parameters, 1 );
+      logger.writeParameter< int >( "Restarting step max:", "gmres-restarting-step-max", parameters, 1 );
+   }
    logger.writeParameter< double >( "Convergence residue:", "convergence-residue", parameters );
    logger.writeParameter< double >( "Divergence residue:", "divergence-residue", parameters );
    logger.writeParameter< int >( "Maximal number of iterations:", "max-iterations", parameters );
@@ -173,7 +169,7 @@ writeProlog( Logger& logger,
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setTimeStepper( TimeStepper& timeStepper )
 {
    this->timeStepper = &timeStepper;
@@ -182,7 +178,7 @@ setTimeStepper( TimeStepper& timeStepper )
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setProblem( ProblemType& problem )
 {
    this->problem = &problem;
@@ -191,7 +187,7 @@ setProblem( ProblemType& problem )
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setInitialTime( const RealType& initialTime )
 {
    this->initialTime = initialTime;
@@ -200,7 +196,7 @@ setInitialTime( const RealType& initialTime )
 template< typename Problem,
           typename TimeStepper >
 const typename TimeStepper :: RealType&
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 getInitialTime() const
 {
    return this->initialTime;
@@ -210,12 +206,12 @@ getInitialTime() const
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setFinalTime( const RealType& finalTime )
 {
    if( finalTime <= this->initialTime )
    {
-      std::cerr << "Final time for PDESolver must larger than the initial time which is now " << this->initialTime << "." << std::endl;
+      std::cerr << "Final time for TimeDependentPDESolver must larger than the initial time which is now " << this->initialTime << "." << std::endl;
       return false;
    }
    this->finalTime = finalTime;
@@ -225,7 +221,7 @@ setFinalTime( const RealType& finalTime )
 template< typename Problem,
           typename TimeStepper >
 const typename TimeStepper :: RealType&
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 getFinalTime() const
 {
    return this->finalTime;
@@ -234,12 +230,12 @@ getFinalTime() const
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setSnapshotPeriod( const RealType& period )
 {
    if( period <= 0 )
    {
-      std::cerr << "Snapshot tau for PDESolver must be positive value." << std::endl;
+      std::cerr << "Snapshot tau for TimeDependentPDESolver must be positive value." << std::endl;
       return false;
    }
    this->snapshotPeriod = period;
@@ -249,7 +245,7 @@ setSnapshotPeriod( const RealType& period )
 template< typename Problem,
           typename TimeStepper >
 const typename TimeStepper::RealType&
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 getSnapshotPeriod() const
 {
    return this->snapshotPeriod;
@@ -258,12 +254,12 @@ getSnapshotPeriod() const
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setTimeStep( const RealType& timeStep )
 {
    if( timeStep <= 0 )
    {
-      std::cerr << "The time step for PDESolver must be positive value." << std::endl;
+      std::cerr << "The time step for TimeDependentPDESolver must be positive value." << std::endl;
       return false;
    }
    this->timeStep = timeStep;
@@ -273,7 +269,7 @@ setTimeStep( const RealType& timeStep )
 template< typename Problem,
           typename TimeStepper >
 const typename TimeStepper::RealType&
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 getTimeStep() const
 {
    return this->timeStep;
@@ -282,12 +278,12 @@ getTimeStep() const
 template< typename Problem,
           typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setTimeStepOrder( const RealType& timeStepOrder )
 {
    if( timeStepOrder < 0 )
    {
-      std::cerr << "The time step order for PDESolver must be zero or positive value." << std::endl;
+      std::cerr << "The time step order for TimeDependentPDESolver must be zero or positive value." << std::endl;
       return false;
    }
    this->timeStepOrder = timeStepOrder;
@@ -297,37 +293,35 @@ setTimeStepOrder( const RealType& timeStepOrder )
 template< typename Problem,
           typename TimeStepper >
 const typename TimeStepper::RealType&
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 getTimeStepOrder() const
 {
    return this->timeStepOrder;
 }
 
 template< typename Problem, typename TimeStepper >
-void PDESolver< Problem, TimeStepper > :: setIoTimer( Timer& ioTimer )
+void TimeDependentPDESolver< Problem, TimeStepper > :: setIoTimer( Timer& ioTimer )
 {
    this->ioTimer = &ioTimer;
 }
 
 template< typename Problem, typename TimeStepper >
-void PDESolver< Problem, TimeStepper > :: setComputeTimer( Timer& computeTimer )
+void TimeDependentPDESolver< Problem, TimeStepper > :: setComputeTimer( Timer& computeTimer )
 {
    this->computeTimer = &computeTimer;
 }
 
 template< typename Problem, typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 solve()
 {
-   Assert( timeStepper != 0,
-              std::cerr << "No time stepper was set in PDESolver." );
-   Assert( problem != 0,
-              std::cerr << "No problem was set in PDESolver." );
+   TNL_ASSERT_TRUE( timeStepper, "No time stepper was set in PDESolver." );
+   TNL_ASSERT_TRUE( problem, "No problem was set in PDESolver." );
 
    if( snapshotPeriod == 0 )
    {
-      std::cerr << "No snapshot tau was set in PDESolver." << std::endl;
+      std::cerr << "No snapshot tau was set in TimeDependentPDESolver." << std::endl;
       return false;
    }
    RealType t( this->initialTime );
@@ -338,7 +332,7 @@ solve()
    this->computeTimer->reset();
  
    this->ioTimer->start();
-   if( ! this->problem->makeSnapshot( t, step, meshPointer, this->dofsPointer, this->meshDependentData ) )
+   if( ! this->problem->makeSnapshot( t, step, meshPointer, this->dofsPointer, this->meshDependentDataPointer ) )
    {
       std::cerr << "Making the snapshot failed." << std::endl;
       return false;
@@ -356,14 +350,14 @@ solve()
    {
       RealType tau = min( this->snapshotPeriod,
                           this->finalTime - t );
-      if( ! this->timeStepper->solve( t, t + tau, this->meshPointer, this->dofsPointer, this->meshDependentData ) )
+      if( ! this->timeStepper->solve( t, t + tau, this->meshPointer, this->dofsPointer, this->meshDependentDataPointer ) )
          return false;
       step ++;
       t += tau;
 
       this->ioTimer->start();
       this->computeTimer->stop();
-      if( ! this->problem->makeSnapshot( t, step, this->meshPointer, this->dofsPointer, this->meshDependentData ) )
+      if( ! this->problem->makeSnapshot( t, step, this->meshPointer, this->dofsPointer, this->meshDependentDataPointer ) )
       {
          std::cerr << "Making the snapshot failed." << std::endl;
          return false;
@@ -377,7 +371,7 @@ solve()
 
 template< typename Problem, typename TimeStepper >
 bool
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 writeEpilog( Logger& logger ) const
 {
    return ( this->timeStepper->writeEpilog( logger ) &&
diff --git a/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h b/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..41b6a47b5135fa74822804b5551f0dabbc81a3d4
--- /dev/null
+++ b/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+                          tnlTimeIndependentPDESolver.h  -  description
+                             -------------------
+    begin                : Jan 15, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once
+
+#include <core/tnlObject.h>
+#include <config/tnlConfigDescription.h>
+#include <TNL/Config/ParameterContainer.h>
+#include <solvers/tnlSolverMonitor.h>
+#include <core/tnlLogger.h>
+
+template< typename Problem >
+class tnlTimeIndependentPDESolver : public tnlObject
+{
+   public:
+
+      typedef Problem ProblemType;
+      typedef typename ProblemType::RealType RealType;
+      typedef typename ProblemType::DeviceType DeviceType;
+      typedef typename ProblemType::IndexType IndexType;
+      typedef typename ProblemType::MeshType MeshType;
+      typedef typename ProblemType::DofVectorType DofVectorType;
+      typedef typename ProblemType::MeshDependentDataType MeshDependentDataType;      
+
+      tnlTimeIndependentPDESolver();
+
+      static void configSetup( tnlConfigDescription& config,
+                               const String& prefix = "" );
+
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" );
+
+      bool writeProlog( tnlLogger& logger,
+                        const Config::ParameterContainer& parameters );
+
+
+      void setProblem( ProblemType& problem );
+
+      void setComputeTimer( tnlTimer& computeTimer );
+      
+      void setIoTimer( tnlTimer& ioTimer );
+
+      bool solve();
+
+      bool writeEpilog( tnlLogger& logger ) const;
+
+   protected:
+
+      MeshType mesh;
+
+      DofVectorType dofs;
+
+      MeshDependentDataType meshDependentData;
+
+      ProblemType* problem;
+
+      tnlTimer *computeTimer;
+};
+
+#include <solvers/pde/tnlTimeIndependentPDESolver_impl.h>
+
diff --git a/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h b/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..957f710300bbc373b184dbd5736028377b68a7ba
--- /dev/null
+++ b/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+                          tnlTimeIndependentPDESolver_impl.h  -  description
+                             -------------------
+    begin                : Jan 15, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#pragma once 
+
+#include <solvers/pde/tnlTimeIndependentPDESolver.h>
+
+template< typename Problem >
+tnlTimeIndependentPDESolver< Problem >::
+tnlTimeIndependentPDESolver()
+: problem( 0 ),
+  computeTimer( 0 )
+{
+}
+
+template< typename Problem >
+void
+tnlTimeIndependentPDESolver< Problem >::
+configSetup( tnlConfigDescription& config,
+             const String& prefix )
+{
+}
+
+template< typename Problem >
+bool
+tnlTimeIndependentPDESolver< Problem >::
+setup( const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   /****
+    * Load the mesh from the mesh file
+    */
+   const String& meshFile = parameters.getParameter< String >( "mesh" );
+   cout << "Loading a mesh from the file " << meshFile << "...";
+   if( ! this->mesh.load( meshFile ) )
+   {
+      cerr << endl;
+      cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl;
+      cerr << " You may create it with tools like tnl-grid-setup or tnl-mesh-convert." << endl;
+      return false;
+   }
+   cout << " [ OK ] " << endl;
+
+   /****
+    * Set DOFs (degrees of freedom)
+    */
+   TNL_ASSERT_GT( problem->getDofs( this->mesh ), 0, "number of DOFs must be positive" );
+   this->dofs.setSize( problem->getDofs( this->mesh ) );
+   this->dofs.setValue( 0.0 );
+   this->problem->bindDofs( this->mesh, this->dofs );   
+   
+   /****
+    * Set mesh dependent data
+    */
+   this->problem->setMeshDependentData( this->mesh, this->meshDependentData );
+   this->problem->bindMeshDependentData( this->mesh, this->meshDependentData );
+   
+   /***
+    * Set-up the initial condition
+    */
+   cout << "Setting up the initial condition ... ";
+   typedef typename Problem :: DofVectorType DofVectorType;
+   if( ! this->problem->setInitialData( parameters, this->mesh, this->dofs, this->meshDependentData ) )
+      return false;
+   cout << " [ OK ]" << endl;
+   
+   return true;
+}
+
+template< typename Problem >
+bool
+tnlTimeIndependentPDESolver< Problem >::
+writeProlog( tnlLogger& logger,
+             const Config::ParameterContainer& parameters )
+{
+   logger.writeHeader( problem->getPrologHeader() );
+   problem->writeProlog( logger, parameters );
+   logger.writeSeparator();
+   mesh.writeProlog( logger );
+   logger.writeSeparator();
+   const String& solverName = parameters. getParameter< String >( "discrete-solver" );
+   logger.writeParameter< String >( "Discrete solver:", "discrete-solver", parameters );
+   if( solverName == "merson" )
+      logger.writeParameter< double >( "Adaptivity:", "merson-adaptivity", parameters, 1 );
+   if( solverName == "sor" )
+      logger.writeParameter< double >( "Omega:", "sor-omega", parameters, 1 );
+   if( solverName == "gmres" )
+      logger.writeParameter< int >( "Restarting:", "gmres-restarting", parameters, 1 );
+   logger.writeParameter< double >( "Convergence residue:", "convergence-residue", parameters );
+   logger.writeParameter< double >( "Divergence residue:", "divergence-residue", parameters );
+   logger.writeParameter< int >( "Maximal number of iterations:", "max-iterations", parameters );
+   logger.writeParameter< int >( "Minimal number of iterations:", "min-iterations", parameters );
+   logger.writeSeparator();
+   logger.writeParameter< String >( "Real type:", "real-type", parameters, 0 );
+   logger.writeParameter< String >( "Index type:", "index-type", parameters, 0 );
+   logger.writeParameter< String >( "Device:", "device", parameters, 0 );
+   logger.writeSeparator();
+   logger.writeSystemInformation( parameters );
+   logger.writeSeparator();
+   logger.writeCurrentTime( "Started at:" );
+   logger.writeSeparator();
+   return true;
+}
+
+template< typename Problem >
+void
+tnlTimeIndependentPDESolver< Problem >::
+setProblem( ProblemType& problem )
+{
+   this->problem = &problem;
+}
+
+template< typename Problem >
+void tnlTimeIndependentPDESolver< Problem > :: setIoTimer( tnlTimer& ioTimer )
+{
+  // this->ioTimer = &ioTimer;
+}
+
+template< typename Problem >
+void tnlTimeIndependentPDESolver< Problem > :: setComputeTimer( tnlTimer& computeTimer )
+{
+   this->computeTimer = &computeTimer;
+}
+
+template< typename Problem >
+bool
+tnlTimeIndependentPDESolver< Problem >::
+solve()
+{
+   TNL_ASSERT_TRUE( problem, "No problem was set in tnlPDESolver." );
+
+   this->computeTimer->reset();
+   this->computeTimer->start();
+   if( ! this->problem->solve( this->mesh, this->dofs ) )
+   {
+      this->computeTimer->stop();
+      return false;
+   }
+   this->computeTimer->stop();
+   return true;
+}
+
+template< typename Problem >
+bool
+tnlTimeIndependentPDESolver< Problem >::
+writeEpilog( tnlLogger& logger ) const
+{
+   return this->problem->writeEpilog( logger );
+}
diff --git a/src/TNL/Solvers/Solver.h b/src/TNL/Solvers/Solver.h
index b1d67352352a5cced97aa9b9bf91d8f0a0ba13b9..0d5925a1eb80b1fc7a81c94d129c70c5de242545 100644
--- a/src/TNL/Solvers/Solver.h
+++ b/src/TNL/Solvers/Solver.h
@@ -17,7 +17,7 @@ namespace Solvers {
 
 template< template< typename Real, typename Device, typename Index, typename MeshType, typename ConfigTag, typename SolverStarter > class ProblemSetter,
           template< typename ConfTag > class ProblemConfig,
-          typename ConfigTag = tnlDefaultBuildConfigTag >
+          typename ConfigTag = DefaultBuildConfigTag >
 class Solver
 {
    public:
diff --git a/src/TNL/Solvers/SolverConfig_impl.h b/src/TNL/Solvers/SolverConfig_impl.h
index 76234b9880e45db4d023fa898622bef75ff361d7..e66397310414edbecc68d7a1090e2186b952f851 100644
--- a/src/TNL/Solvers/SolverConfig_impl.h
+++ b/src/TNL/Solvers/SolverConfig_impl.h
@@ -14,7 +14,7 @@
 #include <TNL/Solvers/BuildConfigTags.h>
 #include <TNL/Solvers/DummyProblem.h>
 #include <TNL/Solvers/PDE/ExplicitTimeStepper.h>
-#include <TNL/Solvers/PDE/PDESolver.h>
+#include <TNL/Solvers/PDE/TimeDependentPDESolver.h>
 
 namespace TNL {
 namespace Solvers {
@@ -26,6 +26,10 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
    typedef DummyProblem< double, Devices::Host, int > DummyProblemType;
 
    config.addDelimiter( " === General parameters ==== " );
+   config.addEntry< bool >( "catch-exceptions",
+                            "Catch C++ exceptions. Disabling it allows the program to drop into the debugger "
+                            "and track the origin of the exception.",
+                            true );
    /****
     * Setup real type
     */
@@ -51,6 +55,12 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
    if( ConfigTagDevice< ConfigTag, Devices::Cuda >::enabled )
       config.addEntryEnum( "cuda" );
 #endif
+   
+#ifdef HAVE_MIC
+   if( ConfigTagDevice< ConfigTag, Devices::MIC >::enabled )
+      config.addEntryEnum( "mic" );
+#endif
+   
 
    /****
     * Setup index type.
@@ -79,7 +89,7 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
     */
    config.addDelimiter( " === Time discretisation parameters ==== " );
    typedef PDE::ExplicitTimeStepper< DummyProblemType, ODE::Euler > ExplicitTimeStepper;
-   PDE::PDESolver< DummyProblemType, ExplicitTimeStepper >::configSetup( config );
+   PDE::TimeDependentPDESolver< DummyProblemType, ExplicitTimeStepper >::configSetup( config );
    ExplicitTimeStepper::configSetup( config );
    if( ConfigTagTimeDiscretisation< ConfigTag, ExplicitTimeDiscretisationTag >::enabled ||
        ConfigTagTimeDiscretisation< ConfigTag, SemiImplicitTimeDiscretisationTag >::enabled ||
@@ -107,6 +117,8 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
          config.addEntryEnum( "cg" );
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitBICGStabSolverTag >::enabled )
          config.addEntryEnum( "bicgstab" );
+      if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitBICGStabLSolverTag >::enabled )
+         config.addEntryEnum( "bicgstabl" );
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitCWYGMRESSolverTag >::enabled )
          config.addEntryEnum( "cwygmres" );
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitGMRESSolverTag >::enabled )
@@ -116,13 +128,17 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitSORSolverTag >::enabled )
          config.addEntryEnum( "sor" );
 #ifdef HAVE_UMFPACK
-      if( MeshConfigSemiImplicitSolver< MeshConfig, SemiImplicitUmfpackSolverTag >::enabled )
+      if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitUmfpackSolverTag >::enabled )
          config.addEntryEnum( "umfpack" );
 #endif
    }
    config.addEntry< String >( "preconditioner", "The preconditioner for the discrete solver:", "none" );
    config.addEntryEnum( "none" );
    config.addEntryEnum( "diagonal" );
+// TODO: implement parallel ILU or device-dependent build config tags for preconditioners
+#ifndef HAVE_CUDA
+   config.addEntryEnum( "ilu0" );
+#endif
    if( ConfigTagTimeDiscretisation< ConfigTag, ExplicitTimeDiscretisationTag >::enabled ||
        ConfigTagTimeDiscretisation< ConfigTag, SemiImplicitTimeDiscretisationTag >::enabled )
    {
@@ -147,10 +163,15 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
          Linear::CG< MatrixType >::configSetup( config );
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitBICGStabSolverTag >::enabled )
          Linear::BICGStab< MatrixType >::configSetup( config );
+      if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitBICGStabLSolverTag >::enabled )
+         Linear::BICGStabL< MatrixType >::configSetup( config );
+
+      // GMRES and CWYGMRES have the same options
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitCWYGMRESSolverTag >::enabled )
          Linear::CWYGMRES< MatrixType >::configSetup( config );
-      if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitGMRESSolverTag >::enabled )
+      else if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitGMRESSolverTag >::enabled )
          Linear::GMRES< MatrixType >::configSetup( config );
+
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitTFQMRSolverTag >::enabled )
          Linear::TFQMR< MatrixType >::configSetup( config );
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitSORSolverTag >::enabled )
@@ -167,4 +188,3 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
 
 } // namespace Solvers
 } // namespace TNL
-
diff --git a/src/TNL/Solvers/SolverInitiator_impl.h b/src/TNL/Solvers/SolverInitiator_impl.h
index c826563a3e2717c7119ad6e464b5521e228d04a2..1b5ddc1a3bd15ccd16cb4bcfa7bc6940f7342134 100644
--- a/src/TNL/Solvers/SolverInitiator_impl.h
+++ b/src/TNL/Solvers/SolverInitiator_impl.h
@@ -17,6 +17,7 @@
 #include <TNL/Solvers/Linear/GMRES.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Devices/MIC.h>
 
 namespace TNL {
 namespace Solvers {   
@@ -75,6 +76,8 @@ class SolverInitiatorRealResolver< ProblemSetter, Real, ConfigTag, true >
             return SolverInitiatorDeviceResolver< ProblemSetter, Real, Devices::Host, ConfigTag >::run( parameters );
          if( device == "cuda" )
             return SolverInitiatorDeviceResolver< ProblemSetter, Real, Devices::Cuda, ConfigTag >::run( parameters );
+         if(device == "mic")
+             return SolverInitiatorDeviceResolver< ProblemSetter, Real, Devices::MIC, ConfigTag >::run( parameters );
          std::cerr << "The device '" << device << "' is not defined. " << std::endl;
          return false;
       }
diff --git a/src/TNL/Solvers/SolverMonitor.h b/src/TNL/Solvers/SolverMonitor.h
index cbd8bef7240f01a0878dd53e2b03c6179b284e53..124bf1a839f01b720bf35a0a9d2c39d25d3fde22 100644
--- a/src/TNL/Solvers/SolverMonitor.h
+++ b/src/TNL/Solvers/SolverMonitor.h
@@ -20,16 +20,15 @@ namespace Solvers {
 
 class SolverMonitor
 {
-   public:
-
+public:
    SolverMonitor()
-      : timeout_milliseconds(500),
-        stopped(true)
-   {};
+      : timeout_milliseconds( 500 ),
+        started( false ),
+        stopped( false ),
+        timer( nullptr )
+   {}
 
-   ~SolverMonitor() {};
- 
-   virtual void refresh( bool force = false ) = 0;
+   virtual void refresh() = 0;
 
    void setRefreshRate( const int& refreshRate )
    {
@@ -43,13 +42,17 @@ class SolverMonitor
 
    void runMainLoop()
    {
-      stopped = false;
+      // We need to use both 'started' and 'stopped' to avoid a deadlock
+      // when the loop thread runs this method delayed after the
+      // SolverMonitorThread's destructor has already called stopMainLoop()
+      // from the main thread.
+      started = true;
 
       const int timeout_base = 100;
       const std::chrono::milliseconds timeout( timeout_base );
 
       while( ! stopped ) {
-         refresh( true );
+         refresh();
 
          // make sure to detect changes to refresh rate
          int steps = timeout_milliseconds / timeout_base;
@@ -61,6 +64,10 @@ class SolverMonitor
             std::this_thread::sleep_for( timeout );
          }
       }
+
+      // reset to initial state
+      started = false;
+      stopped = false;
    }
 
    void stopMainLoop()
@@ -68,8 +75,12 @@ class SolverMonitor
       stopped = true;
    }
 
-   protected:
+   bool isStopped() const
+   {
+      return stopped;
+   }
 
+protected:
    double getElapsedTime()
    {
       if( ! timer )
@@ -79,7 +90,7 @@ class SolverMonitor
 
    std::atomic_int timeout_milliseconds;
 
-   std::atomic_bool stopped;
+   std::atomic_bool started, stopped;
 
    Timer* timer;
 };
@@ -110,4 +121,3 @@ class SolverMonitorThread
 
 } // namespace Solvers
 } // namespace TNL
-
diff --git a/src/TNL/Solvers/SolverStarter_impl.h b/src/TNL/Solvers/SolverStarter_impl.h
index 50c3e3bad93cb3870659a9fffa2ce36f8526fcff..a8fae47d95980bf6f1414c6adeb38c1413a82fa0 100644
--- a/src/TNL/Solvers/SolverStarter_impl.h
+++ b/src/TNL/Solvers/SolverStarter_impl.h
@@ -14,20 +14,24 @@
 #include <TNL/Logger.h>
 #include <TNL/String.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Solvers/SolverStarter.h>
+#include <TNL/Solvers/BuildConfigTags.h>
 #include <TNL/Solvers/ODE/Merson.h>
 #include <TNL/Solvers/ODE/Euler.h>
 #include <TNL/Solvers/Linear/SOR.h>
 #include <TNL/Solvers/Linear/CG.h>
 #include <TNL/Solvers/Linear/BICGStab.h>
+#include <TNL/Solvers/Linear/BICGStabL.h>
 #include <TNL/Solvers/Linear/GMRES.h>
 #include <TNL/Solvers/Linear/CWYGMRES.h>
 #include <TNL/Solvers/Linear/TFQMR.h>
 #include <TNL/Solvers/Linear/UmfpackWrapper.h>
 #include <TNL/Solvers/Linear/Preconditioners/Dummy.h>
 #include <TNL/Solvers/Linear/Preconditioners/Diagonal.h>
+#include <TNL/Solvers/Linear/Preconditioners/ILU0.h>
 #include <TNL/Solvers/PDE/ExplicitTimeStepper.h>
 #include <TNL/Solvers/PDE/SemiImplicitTimeStepper.h>
-#include <TNL/Solvers/PDE/PDESolver.h>
+#include <TNL/Solvers/PDE/TimeDependentPDESolver.h>
 
 namespace TNL {
 namespace Solvers {   
@@ -79,12 +83,6 @@ bool SolverStarter< ConfigTag > :: run( const Config::ParameterContainer& parame
        ! Devices::Cuda::setup( parameters ) )
       return false;
    Problem problem;
-   /*if( ! problem.setup( parameters ) )
-   {
-      std::cerr << "The problem initiation failed!" << std::endl;
-      return false;
-   }*/
-
    return tnlUserDefinedTimeDiscretisationSetter< Problem, ConfigTag >::run( problem, parameters );
 }
 
@@ -185,23 +183,25 @@ class SolverStarterTimeDiscretisationSetter< Problem, SemiImplicitTimeDiscretisa
          if( discreteSolver != "sor" &&
              discreteSolver != "cg" &&
              discreteSolver != "bicgstab" &&
+             discreteSolver != "bicgstabl" &&
              discreteSolver != "gmres" &&
              discreteSolver != "cwygmres" &&
              discreteSolver != "tfqmr" )
          {
-            std::cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, gmres, cwygmres or tfqmr." << std::endl;
+            std::cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, bicgstabl, gmres, cwygmres or tfqmr." << std::endl;
             return false;
          }
 #else
          if( discreteSolver != "sor" &&
              discreteSolver != "cg" &&
              discreteSolver != "bicgstab" &&
+             discreteSolver != "bicgstabl" &&
              discreteSolver != "gmres" &&
              discreteSolver != "cwygmres" &&
              discreteSolver != "tfqmr" &&
              discreteSolver != "umfpack" )
          {
-            std::cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, gmres, cwygmres, tfqmr or umfpack." << std::endl;
+            std::cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, bicgstabl, gmres, cwygmres, tfqmr or umfpack." << std::endl;
             return false;
          }
 #endif
@@ -212,6 +212,8 @@ class SolverStarterTimeDiscretisationSetter< Problem, SemiImplicitTimeDiscretisa
             return SolverStarterPreconditionerSetter< Problem, SemiImplicitCGSolverTag, ConfigTag >::run( problem, parameters );
          if( discreteSolver == "bicgstab" )
             return SolverStarterPreconditionerSetter< Problem, SemiImplicitBICGStabSolverTag, ConfigTag >::run( problem, parameters );
+         if( discreteSolver == "bicgstabl" )
+            return SolverStarterPreconditionerSetter< Problem, SemiImplicitBICGStabLSolverTag, ConfigTag >::run( problem, parameters );
          if( discreteSolver == "gmres" )
             return SolverStarterPreconditionerSetter< Problem, SemiImplicitGMRESSolverTag, ConfigTag >::run( problem, parameters );
          if( discreteSolver == "cwygmres" )
@@ -234,7 +236,7 @@ class SolverStarterTimeDiscretisationSetter< Problem, ImplicitTimeDiscretisation
       static bool run( Problem& problem,
                        const Config::ParameterContainer& parameters )
       {
-         const String& discreteSolver = parameters. getParameter< String>( "discrete-solver" );
+//         const String& discreteSolver = parameters. getParameter< String>( "discrete-solver" );
          return false;
       }
 };
@@ -292,8 +294,10 @@ class SolverStarterPreconditionerSetter
             return SolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, Linear::Preconditioners::Dummy, ConfigTag >::run( problem, parameters );
          if( preconditioner == "diagonal" )
             return SolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, Linear::Preconditioners::Diagonal, ConfigTag >::run( problem, parameters );
+         if( preconditioner == "ilu0" )
+            return SolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, Linear::Preconditioners::ILU0, ConfigTag >::run( problem, parameters );
 
-         std::cerr << "Unknown preconditioner " << preconditioner << ". It can be only: none, diagonal." << std::endl;
+         std::cerr << "Unknown preconditioner " << preconditioner << ". It can be only: none, diagonal, ilu0." << std::endl;
          return false;
       }
 };
@@ -362,42 +366,58 @@ bool SolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
    timeStepper.setSolver( discreteSolver );
 
    /****
-    * Set-up the PDE solver
+    * Open the log file
     */
-   PDE::PDESolver< Problem, TimeStepper > solver;
-   solver.setProblem( problem );
-   solver.setTimeStepper( timeStepper );
-   if( ! solver.setup( parameters ) )
+   const String logFileName = parameters.getParameter< String >( "log-file" );
+   std::ofstream logFile( logFileName.getString() );
+   if( ! logFile ) {
+      std::cerr << "Unable to open the log file " << logFileName << "." << std::endl;
       return false;
+   }
 
    /****
-    * Write a prolog
+    * Set-up the PDE solver
     */
-   int verbose = parameters.getParameter< int >( "verbose" );
-   parameters. getParameter< int >( "log-width", logWidth );
-   if( verbose )
-   {
-      Logger logger( logWidth,std::cout );
-      solver.writeProlog( logger, parameters );
-   }
-   String logFileName;
-   bool haveLogFile = parameters.getParameter< String >( "log-file", logFileName );
-   if( haveLogFile )
-   {
-      std::fstream logFile;
-      logFile.open( logFileName.getString(), std::ios::out );
-      if( ! logFile )
-      {
-         std::cerr << "Unable to open the log file " << logFileName << "." << std::endl;
+   PDE::TimeDependentPDESolver< Problem, TimeStepper > solver;
+   // catching exceptions ala gtest:
+   // https://github.com/google/googletest/blob/59c795ce08be0c8b225bc894f8da6c7954ea5c14/googletest/src/gtest.cc#L2409-L2431
+   const int catch_exceptions = parameters.getParameter< bool >( "catch-exceptions" );
+   if( catch_exceptions ) {
+      try {
+         solver.setProblem( problem );
+         solver.setTimeStepper( timeStepper );
+         if( ! solver.setup( parameters ) )
+            return false;
+      }
+      catch ( const std::exception& e ) {
+         std::cerr << "Setting up the solver failed due to a C++ exception with description: " << e.what() << std::endl;
+         logFile   << "Setting up The solver failed due to a C++ exception with description: " << e.what() << std::endl;
          return false;
       }
-      else
-      {
-         Logger logger( logWidth, logFile );
-         solver.writeProlog( logger, parameters  );
-         logFile.close();
+      catch (...) {
+         std::cerr << "Setting up the solver failed due to an unknown C++ exception." << std::endl;
+         logFile   << "Setting up The solver failed due to an unknown C++ exception." << std::endl;
+         throw;
       }
    }
+   else {
+      solver.setProblem( problem );
+      solver.setTimeStepper( timeStepper );
+      if( ! solver.setup( parameters ) )
+         return false;
+   }
+
+   /****
+    * Write a prolog
+    */
+   const int verbose = parameters.getParameter< int >( "verbose" );
+   parameters.getParameter< int >( "log-width", logWidth );
+   if( verbose ) {
+      Logger logger( logWidth, std::cout );
+      solver.writeProlog( logger, parameters );
+   }
+   Logger logger( logWidth, logFile );
+   solver.writeProlog( logger, parameters  );
 
    /****
     * Set-up solver monitor and launch the main loop.
@@ -424,25 +444,34 @@ bool SolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
    /****
     * Start the solver
     */
-   bool returnCode = solver.solve();
-   solverMonitorPointer->stopMainLoop();
-   if( ! returnCode )
-   {
-      if( verbose )
-         std::cerr << std::endl << "The solver did not converge. " << std::endl;
-      std::fstream logFile;
-      logFile.open( logFileName.getString(), std::ios::out | std::ios::app );
-      if( ! logFile )
-      {
-         std::cerr << "Unable to open the log file " << logFileName << "." << std::endl;
+   bool returnCode = true;
+   // catching exceptions ala gtest:
+   // https://github.com/google/googletest/blob/59c795ce08be0c8b225bc894f8da6c7954ea5c14/googletest/src/gtest.cc#L2409-L2431
+   if( catch_exceptions ) {
+      try {
+         returnCode = solver.solve();
+      }
+      catch ( const std::exception& e ) {
+         std::cerr << "The solver failed due to a C++ exception with description: " << e.what() << std::endl;
+         logFile   << "The solver failed due to a C++ exception with description: " << e.what() << std::endl;
          return false;
       }
-      else
-      {
-         logFile << "The solver did not converge. " << std::endl;
-         logFile.close();
+      catch (...) {
+         std::cerr << "The solver failed due to an unknown C++ exception." << std::endl;
+         logFile   << "The solver failed due to an unknown C++ exception." << std::endl;
+         throw;
       }
    }
+   else {
+      returnCode = solver.solve();
+   }
+
+   solverMonitorPointer->stopMainLoop();
+   if( ! returnCode ) {
+      if( verbose )
+         std::cerr << std::endl << "The solver did not converge. " << std::endl;
+      logFile << "The solver did not converge. " << std::endl;
+   }
 
    /****
     * Stop timers
@@ -454,22 +483,10 @@ bool SolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
     * Write an epilog
     */
    if( verbose )
-      writeEpilog(std::cout, solver );
-   if( haveLogFile )
-   {
-      std::fstream logFile;
-      logFile.open( logFileName.getString(), std::ios::out | std::ios::app );
-      if( ! logFile )
-      {
-         std::cerr << "Unable to open the log file " << logFileName << "." << std::endl;
-         return false;
-      }
-      else
-      {
-         writeEpilog( logFile, solver );
-         logFile.close();
-      }
-   }
+      writeEpilog( std::cout, solver );
+   writeEpilog( logFile, solver );
+   logFile.close();
+
    return returnCode;
 }
 
@@ -484,6 +501,11 @@ bool SolverStarter< ConfigTag > :: writeEpilog( std::ostream& str, const Solver&
       return false;
    logger.writeParameter< const char* >( "Compute time:", "" );
    this->computeTimer.writeLog( logger, 1 );
+   if( std::is_same< typename Solver::DeviceType, TNL::Devices::Cuda >::value )
+   {
+      logger.writeParameter< const char* >( "GPU synchronization time:", "" );
+      TNL::Devices::Cuda::smartPointersSynchronizationTimer.writeLog( logger, 1 );
+   }   
    logger.writeParameter< const char* >( "I/O time:", "" );
    this->ioTimer.writeLog( logger, 1 );
    logger.writeParameter< const char* >( "Total time:", "" );
diff --git a/src/TNL/StaticFor.h b/src/TNL/StaticFor.h
index 19eaeaba77b60361c01c9a1e190579bd1f9e4f33..bc63c43848b07251bf92b5db12b2a35f351f9f78 100644
--- a/src/TNL/StaticFor.h
+++ b/src/TNL/StaticFor.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#undef __INTEL_COMPILER
+
 namespace TNL {
 
 template< typename IndexType, IndexType val >
@@ -123,13 +125,13 @@ class StaticFor
    __cuda_callable__
    static void exec()
    {
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
       StaticForExecutor< IndexType,
                          StaticForIndexTag< IndexType, begin >,
                          StaticForIndexTag< IndexType, end - begin >,
                          LoopBody >::exec();
 #else
-     Assert( false, );
+     TNL_ASSERT( false, );
 #endif
    }
 
@@ -137,13 +139,13 @@ class StaticFor
    __cuda_callable__
    static void exec( T &p )
    {
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
       StaticForExecutor< IndexType,
                          StaticForIndexTag< IndexType, begin >,
                          StaticForIndexTag< IndexType, end - begin >,
                          LoopBody >::exec( p );
 #else
-     Assert( false, );
+     TNL_ASSERT( false, );
 #endif
    }
 
@@ -152,13 +154,13 @@ class StaticFor
    __cuda_callable__
    static void exec( T0& p0, T1& p1 )
    {
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
       StaticForExecutor< IndexType,
                          StaticForIndexTag< IndexType, begin >,
                          StaticForIndexTag< IndexType, end - begin >,
                          LoopBody >::exec( p0, p1 );
 #else
-     Assert( false, );
+     TNL_ASSERT( false, );
 #endif
    }
 
@@ -168,13 +170,13 @@ class StaticFor
    __cuda_callable__
    static void exec( T0& p0, T1& p1, T2& p2 )
    {
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
       StaticForExecutor< IndexType,
                          StaticForIndexTag< IndexType, begin >,
                          StaticForIndexTag< IndexType, end - begin >,
                          LoopBody >::exec( p0, p1, p2 );
 #else
-     Assert( false, );
+     TNL_ASSERT( false, );
 #endif
    }
 
@@ -185,13 +187,13 @@ class StaticFor
    __cuda_callable__
    static void exec( T0& p0, T1& p1, T2& p2, T3& p3 )
    {
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
       StaticForExecutor< IndexType,
                          StaticForIndexTag< IndexType, begin >,
                          StaticForIndexTag< IndexType, end - begin >,
                          LoopBody >::exec( p0, p1, p2, p3 );
 #else
-     Assert( false, );
+     TNL_ASSERT( false, );
 #endif
    }
 };
diff --git a/src/TNL/String.cpp b/src/TNL/String.cpp
index 723f024a22e623facf03a9994bfe55f81ac6d6c9..2645801139e3e464037dbe005063d29fb6c676be 100644
--- a/src/TNL/String.cpp
+++ b/src/TNL/String.cpp
@@ -10,10 +10,9 @@
 
 #include <cstring>
 #include <string.h>
-#include <assert.h>
 #include <TNL/String.h>
 #include <TNL/Assert.h>
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/File.h>
 #include <TNL/Math.h>
 #ifdef HAVE_MPI
@@ -24,117 +23,123 @@ namespace TNL {
 
 const unsigned int STRING_PAGE = 256;
 
-String :: String()
+String::String()
+   : string( nullptr ), length( 0 )
 {
-   string = new char[ STRING_PAGE ];
-   string[ 0 ] = 0;
-   length = STRING_PAGE;
+   setString( nullptr );
 }
 
-String :: String( const char* c, int prefix_cut_off, int sufix_cut_off )
-   : string( 0 ), length( 0 )
+String::String( const char* c, int prefix_cut_off, int sufix_cut_off )
+   : string( nullptr ), length( 0 )
 {
    setString( c, prefix_cut_off, sufix_cut_off );
 }
 
-String :: String( const String& str )
-: string( 0 ), length( 0 )
+String::String( const String& str )
+   : string( nullptr ), length( 0 )
 {
-   setString( str. getString() );
+   setString( str.getString() );
 }
 
-String :: String( unsigned number )
-: string( 0 ), length( 0 )
+String String::getType()
 {
-   this->setString( convertToString( number ).getString() );
-}
-
-String :: String( int number )
-: string( 0 ), length( 0 )
-{
-   this->setString( convertToString( number ).getString() );
+   return String( "String" );
 }
 
-String :: String( long int number )
-: string( 0 ), length( 0 )
+String::~String()
 {
-   this->setString( convertToString( number ).getString() );
+   if( string ) delete[] string;
 }
 
-String :: String( float number )
-: string( 0 ), length( 0 )
+int String::getLength() const
 {
-   this->setString( convertToString( number ).getString() );
+   return getSize();
 }
 
-String :: String( double number )
-: string( 0 ), length( 0 )
+int String::getSize() const
 {
-   this->setString( convertToString( number ).getString() );
+   return strlen( string );
 }
 
-String String :: getType()
+int String::getAllocatedSize() const
 {
-   return String( "String" );
+   return length;
 }
 
-String :: ~String()
+void String::setSize( int size )
 {
-   if( string ) delete[] string;
+   TNL_ASSERT_GE( size, 0, "string size must be non-negative" );
+   const int _length = STRING_PAGE * ( size / STRING_PAGE + 1 );
+   TNL_ASSERT_GE( _length, 0, "_length size must be non-negative" );
+   if( length != _length ) {
+      if( string ) {
+         delete[] string;
+         string = nullptr;
+      }
+      string = new char[ _length ];
+      length = _length;
+   }
 }
 
-void String :: setString( const char* c, int prefix_cut_off, int sufix_cut_off )
+void String::setString( const char* c, int prefix_cut_off, int sufix_cut_off )
 {
-   if( ! c )
-   {
+   if( ! c ) {
       if( ! string )
-      {
-         string = new char[ STRING_PAGE ];
-         length = STRING_PAGE;
-      }
+         setSize( 1 );
       string[ 0 ] = 0;
       return;
    }
-   int c_len = ( int ) strlen( c );
-   int _length = max( 0, c_len - prefix_cut_off - sufix_cut_off );
+   const int c_len = ( int ) strlen( c );
+   const int _length = max( 0, c_len - prefix_cut_off - sufix_cut_off );
 
    if( length < _length || length == 0 )
-   {
-      if( string ) delete[] string;
-      length = STRING_PAGE * ( _length / STRING_PAGE + 1 );
-      string = new char[ length ];
-   }
-   Assert( string, );
-   memcpy( string, c + min( c_len, prefix_cut_off ), sizeof( char ) * ( _length ) );
+      setSize( _length );
+   TNL_ASSERT( string, );
+   memcpy( string, c + min( c_len, prefix_cut_off ), _length * sizeof( char ) );
    string[ _length ] = 0;
 }
 
-const char& String :: operator[]( int i ) const
+const char* String::getString() const
+{
+   return string;
+}
+
+char* String::getString()
 {
-   Assert( i >= 0 && i < length,
-              std::cerr << "Accessing char outside the string." );
+   return string;
+}
+
+
+const char& String::operator[]( int i ) const
+{
+   TNL_ASSERT( i >= 0 && i < length,
+               std::cerr << "Accessing char outside the string." );
    return string[ i ];
 }
 
-char& String :: operator[]( int i )
+char& String::operator[]( int i )
 {
-   Assert( i >= 0 && i < length,
-              std::cerr << "Accessing char outside the string." );
+   TNL_ASSERT( i >= 0 && i < length,
+               std::cerr << "Accessing char outside the string." );
    return string[ i ];
 }
 
-String& String :: operator = ( const String& str )
+
+/****
+ * Operators for C strings
+ */
+String& String::operator=( const char* str )
 {
-   setString( str. getString() );
-   return * this;
+   setString( str );
+   return *this;
 }
 
-String& String :: operator += ( const char* str )
+String& String::operator+=( const char* str )
 {
    if( str )
    {
-      int len1 = strlen( string );
-      int len2 = strlen( str );
+      const int len1 = strlen( string );
+      const int len2 = strlen( str );
       if( len1 + len2 < length )
          memcpy( string + len1, str, sizeof( char ) * ( len2 + 1 ) );
       else
@@ -146,12 +151,70 @@ String& String :: operator += ( const char* str )
          memcpy( string + len1, str, sizeof( char ) * ( len2 + 1 ) );
       }
    }
-   return * this;
+   return *this;
 }
 
-String& String :: operator += ( const char str )
+String String::operator+( const char* str ) const
 {
-   int len1 = strlen( string );
+   return String( *this ) += str;
+}
+
+bool String::operator==( const char* str ) const
+{
+   TNL_ASSERT( string && str, );
+   return strcmp( string, str ) == 0;
+}
+
+bool String::operator!=( const char* str ) const
+{
+   return ! operator==( str );
+}
+
+
+/****
+ * Operators for Strings
+ */
+String& String::operator=( const String& str )
+{
+   setString( str.getString() );
+   return *this;
+}
+
+String& String::operator+=( const String& str )
+{
+   return operator+=( str.getString() );
+}
+
+String String::operator+( const String& str ) const
+{
+   return String( *this ) += str;
+}
+
+bool String::operator==( const String& str ) const
+{
+   TNL_ASSERT( string && str.string, );
+   return strcmp( string, str.string ) == 0;
+}
+
+bool String::operator!=( const String& str ) const
+{
+   return ! operator==( str );
+}
+
+
+/****
+ * Operators for single characters
+ */
+String& String::operator=( char str )
+{
+   string[ 0 ] = str;
+   string[ 1 ] = 0;
+   return *this;
+}
+
+String& String::operator+=( const char str )
+{
+   const int len1 = strlen( string );
    if( len1 + 1 < length )
    {
       string[ len1 ] = str;
@@ -167,217 +230,153 @@ String& String :: operator += ( const char str )
       string[ len1 + 1 ] = 0;
    }
 
-   return * this;
+   return *this;
 }
 
-String& String :: operator += ( const String& str )
-{
-   return operator += ( str. getString() );
-}
-
-String String :: operator + ( const String& str ) const
+String String::operator+( char str ) const
 {
    return String( *this ) += str;
 }
 
-String String :: operator + ( const char* str ) const
+bool String::operator==( char str ) const
 {
-   return String( *this ) += str;
+   return *this == String( str );
 }
 
-bool String :: operator == ( const String& str ) const
+bool String::operator!=( char str ) const
 {
-   assert( string && str. string );
-   if( str. length != length )
-      return false;
-   if( strcmp( string, str. string ) == 0 )
-      return true;
-   return false;
-}
-
-bool String :: operator != ( const String& str ) const
-{
-   return ! operator == ( str );
+   return ! operator==( str );
 }
 
-bool String :: operator == ( const char* str ) const
-{
-   //cout << ( void* ) string << " " << ( void* ) str << std::endl;
-   assert( string && str );
-   if( strcmp( string, str ) == 0 ) return true;
-   return false;
-}
 
-String :: operator bool () const
+String::operator bool () const
 {
    if( string[ 0 ] ) return true;
    return false;
 }
 
-bool String :: operator != ( const char* str ) const
-{
-   return ! operator == ( str );
-}
-
-int String :: getLength() const
+bool String::operator!() const
 {
-   return strlen( string );
+   return ! operator bool();
 }
 
-void
-String::
-replace( const String& pattern,
-         const String& replaceWith )
+String String::replace( const String& pattern,
+                        const String& replaceWith,
+                        int count ) const
 {
-   int occurences( 0 );
-   int patternLength = pattern.getLength();
    const int length = this->getLength();
-   int patternPointer( 0 );
+   const int patternLength = pattern.getLength();
+   const int replaceWithLength = replaceWith.getLength();
+
+   int patternPointer = 0;
+   int occurrences = 0;
    for( int i = 0; i < length; i++ )
    {
       if( this->string[ i ] == pattern[ patternPointer ] )
          patternPointer++;
       if( patternPointer == patternLength )
       {
-         occurences++;
+         occurrences++;
          patternPointer = 0;
       }
    }
-   const int replaceWithLength = replaceWith.getLength();
-   int newStringLength = length + occurences * ( replaceWithLength - patternLength );
-   char* newString = new char[ newStringLength ];
-   int newStringPointer( 0 );
-   int lastPatternStart( 0 );
-   for( int i = 0; i < length; i++ )
-   {
+   if( count > 0 && occurrences > count )
+      occurrences = count;
+
+   String newString;
+   const int newStringLength = length + occurrences * ( replaceWithLength - patternLength );
+   newString.setSize( newStringLength );
+
+   int newStringHead = 0;
+   patternPointer = 0;
+   occurrences = 0;
+   for( int i = 0; i < length; i++ ) {
+      // copy current character
+      newString[ newStringHead++ ] = this->string[ i ];
+
+      // check if pattern matches
       if( this->string[ i ] == pattern[ patternPointer ] )
-      {
-         if( patternPointer == 0 )
-            lastPatternStart = newStringPointer;
          patternPointer++;
-      }
-      newString[ newStringPointer++ ] = this->string[ i ];
-      if( patternPointer == patternLength )
-      {
-         newStringPointer = lastPatternStart;
-         for( int j = 0; j < replaceWithLength; j++ )
-            newString[ newStringPointer++ ] = replaceWith[ j ];
+      else
+         patternPointer = 0;
+
+      // handle full match
+      if( patternPointer == patternLength ) {
+         // skip unwanted replacements
+         if( count == 0 || occurrences < count ) {
+            newStringHead -= patternLength;
+            for( int j = 0; j < replaceWithLength; j++ )
+               newString[ newStringHead++ ] = replaceWith[ j ];
+         }
+         occurrences++;
          patternPointer = 0;
       }
    }
-   delete[] this->string;
-   this->string = newString;
-}
 
+   newString[ newStringHead ] = 0;
 
-const char* String :: getString() const
-{
-   return string;
+   return newString;
 }
 
-char* String :: getString()
+String
+String::strip( char strip ) const
 {
-   return string;
-}
+   int prefix_cut_off = 0;
+   int sufix_cut_off = 0;
 
+   while( prefix_cut_off < getLength() && (*this)[ prefix_cut_off ] == strip )
+      prefix_cut_off++;
 
-bool String :: save( std::ostream& file ) const
-{
-   assert( string );
+   while( sufix_cut_off < getLength() && (*this)[ getLength() - 1 - sufix_cut_off ] == strip )
+      sufix_cut_off++;
 
-   int len = strlen( string );
-   file. write( ( char* ) &len, sizeof( int ) );
-   file. write( string, len );
-   if( file. bad() ) return false;
-   return true;
+   if( prefix_cut_off + sufix_cut_off < getLength() )
+      return String( getString(), prefix_cut_off, sufix_cut_off );
+   return "";
 }
 
-bool String :: load( std::istream& file )
+int String::split( Containers::List< String >& list, const char separator ) const
 {
-   int _length;
-   file. read( ( char* ) &_length, sizeof( int ) );
-   if( file. bad() ) return false;
-   if( ! _length )
-   {
-      string[ 0 ] = 0;
-      length = 0;
-      return true;
-   }
-   if( string && length < _length )
-   {
-      delete[] string;
-      string = NULL;
-   }
-   if( ! string )
+   list.reset();
+   String copy( *this );
+   int len = copy.getLength();
+   for( int i = 0; i < len; i ++ )
+      if( copy[ i ] == separator )
+         copy[ i ] = 0;
+   for( int i = 0; i < len; i ++ )
    {
-      //dbgCout( "Reallocating string..." );
-      length = STRING_PAGE * ( _length / STRING_PAGE + 1 );
-      string = new char[ length ];
+      if( copy[ i ] == 0 ) continue;
+      String new_string;
+      new_string.setString( &copy.getString()[ i ] );
+      i += new_string.getLength();
+      list.Append( new_string );
    }
-
-   file. read( string, _length );
-   if( file. bad() ) return false;
-   string[ _length ] = 0;
-   return true;
+   return list.getSize();
 }
 
-bool String :: save( File& file ) const
+
+bool String::save( File& file ) const
 {
-   Assert( string,
+   TNL_ASSERT( string,
               std::cerr << "string = " << string );
 
    int len = strlen( string );
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< int, Devices::Host >( &len ) )
-#else
-   if( ! file. write( &len ) )
-#endif
+   if( ! file.write( &len ) )
       return false;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. write< char, Devices::Host, int >( string, len ) )
-#else
-   if( ! file. write( string, len ) )
-#endif
+   if( ! file.write( string, len ) )
       return false;
    return true;
 }
 
-bool String :: load( File& file )
+bool String::load( File& file )
 {
    int _length;
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< int, Devices::Host >( &_length ) )
-#else
-   if( ! file. read( &_length ) )
-#endif
-   {
+   if( ! file.read( &_length ) ) {
       std::cerr << "I was not able to read String length." << std::endl;
       return false;
    }
-   if( ! _length )
-   {
-      string[ 0 ] = 0;
-      length = 0;
-      return true;
-   }
-   if( string && length < _length )
-   {
-      delete[] string;
-      string = NULL;
-   }
-   if( ! string )
-   {
-      //dbgCout( "Reallocating string..." );
-      length = STRING_PAGE * ( _length / STRING_PAGE + 1 );
-      string = new char[ length ];
-   }
-
-#ifdef HAVE_NOT_CXX11
-   if( ! file. read< char, Devices::Host, int >( string, _length ) )
-#else
-   if( ! file. read( string, _length ) )
-#endif
-   {
+   setSize( _length );
+   if( _length && ! file.read( string, _length ) ) {
       std::cerr << "I was not able to read a String with a length " << length << "." << std::endl;
       return false;
    }
@@ -385,13 +384,13 @@ bool String :: load( File& file )
    return true;
 }
 
-void String :: MPIBcast( int root, MPI_Comm comm )
+void String::MPIBcast( int root, MPI_Comm comm )
 {
 #ifdef HAVE_MPI
    dbgFunctionName( "mString", "MPIBcast" );
    int iproc;
    MPI_Comm_rank( MPI_COMM_WORLD, &iproc );
-   assert( string );
+   TNL_ASSERT( string, );
    int len = strlen( string );
    MPI_Bcast( &len, 1, MPI_INT, root, comm );
    dbgExpr( iproc );
@@ -412,42 +411,28 @@ void String :: MPIBcast( int root, MPI_Comm comm )
 #endif
 }
 
-bool String :: getLine( std::istream& stream )
+bool String::getLine( std::istream& stream )
 {
-   std :: string str;
+   std::string str;
    getline( stream, str );
-   this->setString( str. data() );
+   this->setString( str.c_str() );
    if( ! ( *this ) ) return false;
    return true;
 }
 
-int String :: parse( List< String >& list, const char separator ) const
+String operator+( char string1, const String& string2 )
 {
-   list.reset();
-   String copy( *this );
-   int len = copy. getLength();
-   for( int i = 0; i < len; i ++ )
-      if( copy[ i ] == separator )
-         copy[ i ] = 0;
-   for( int i = 0; i < len; i ++ )
-   {
-      if( copy[ i ] == 0 ) continue;
-      String new_string;
-      new_string. setString( &copy. getString()[ i ] );
-      i += new_string. getLength();
-      list. Append( new_string );
-   }
-   return list. getSize();
+   return String( string1 ) + string2;
 }
 
-String operator + ( const char* string1, const String& string2 )
+String operator+( const char* string1, const String& string2 )
 {
    return String( string1 ) + string2;
 }
 
-std::ostream& operator << ( std::ostream& stream, const String& str )
+std::ostream& operator<<( std::ostream& stream, const String& str )
 {
-   stream << str. getString();
+   stream << str.getString();
    return stream;
 }
 
diff --git a/src/TNL/String.h b/src/TNL/String.h
index 45d94d13b954f93c276320600b442cc872ba9df4..899a0e56286256146f88d86ab5d490463100d712 100644
--- a/src/TNL/String.h
+++ b/src/TNL/String.h
@@ -10,7 +10,6 @@
 
 #pragma once
 
-#include <stdio.h>
 #include <iostream>
 #include <sstream>
 #include <TNL/mpi-supp.h>
@@ -18,8 +17,13 @@
 
 namespace TNL {
 
-template< class T > class List;
 class File;
+namespace Containers {
+   template< class T > class List;
+}
+
+template< typename T >
+String convertToString( const T& value );
 
 //! Class for managing strings
 class String
@@ -30,8 +34,7 @@ class String
    //! Length of the allocated piece of memory
    int length;
 
-   public:
-
+public:
    //! Basic constructor
    String();
 
@@ -40,35 +43,42 @@ class String
        @param sufix_cut_off says the same about sufix.
     */
    String( const char* c,
-              int prefix_cut_off = 0,
-              int sufix_cut_off = 0 );
+           int prefix_cut_off = 0,
+           int sufix_cut_off = 0 );
 
    static String getType();
 
    //! Copy constructor
    String( const String& str );
 
-   //! Convert number to a string
-   String( unsigned number );
+   //! Convert anything to a string
+   template< typename T >
+   String( T value )
+      : string( nullptr ), length( 0 )
+   {
+      setString( convertToString( value ).getString() );
+   }
 
-   String( int number );
- 
-   String( long int number );
+   //! Destructor
+   ~String();
 
-   String( float number );
+   //! Return length of the string
+   int getLength() const;
+   int getSize() const;
 
-   String( double number );
+   //! Return currently allocated size
+   int getAllocatedSize() const;
 
-   //! Destructor
-   ~String();
+   //! Reserve space for given number of characters
+   void setSize( int size );
 
    //! Set string from given char pointer
    /*! @param prefix_cut_off says length of the prefix that is going to be omitted and
        @param sufix_cut_off says the same about sufix.
     */
    void setString( const char* c,
-                     int prefix_cut_off = 0,
-                     int sufix_cut_off = 0 );
+                   int prefix_cut_off = 0,
+                   int sufix_cut_off = 0 );
 
    //! Return pointer to data
    const char* getString() const;
@@ -83,56 +93,46 @@ class String
    char& operator[]( int i );
 
    /****
-    * TODO: the operators do not work properly
-    * for example String + const char*
+    * Operators for C strings
     */
-
-   //! Operator =
-   String& operator = ( const String& str );
-
-   //! Operator +=
-   String& operator += ( const char* str );
-
-   //! Operator +=
-   String& operator += ( const char str );
-
-   //! Operator +=
-   String& operator += ( const String& str );
+   String& operator=( const char* str );
+   String& operator+=( const char* str );
+   String operator+( const char* str ) const;
+   bool operator==( const char* str ) const;
+   bool operator!=( const char* str ) const;
  
-   //! Operator +
-   String operator + ( const String& str ) const;
-
-   //! Operator +
-   String operator + ( const char* str ) const;
-
-   //! Comparison operator
-   bool operator == ( const String& str ) const;
-
-   //! Comparison operator
-   bool operator != ( const String& str ) const;
+   /****
+    * Operators for Strings
+    */
+   String& operator=( const String& str );
+   String& operator+=( const String& str );
+   String operator+( const String& str ) const;
+   bool operator==( const String& str ) const;
+   bool operator!=( const String& str ) const;
 
-   //! Comparison operator
-   bool operator == ( const char* ) const;
+   /****
+    * Operators for single characters
+    */
+   String& operator=( char str );
+   String& operator+=( char str );
+   String operator+( char str ) const;
+   bool operator==( char str ) const;
+   bool operator!=( char str ) const;
 
-   //! Comparison operator
-   bool operator != ( const char* ) const;
- 
-   //! Retyping operator
-   operator bool () const;
+   //! Cast to bool operator
+   operator bool() const;
 
-   //! Return length of the string
-   int getLength() const;
+   //! Cast to bool with negation operator
+   bool operator!() const;
 
-   void replace( const String& pattern,
-                 const String& replaceWith );
+   String replace( const String& pattern,
+                   const String& replaceWith,
+                   int count = 0 ) const;
 
-   // TODO: remove
-   //! Write to a binary file
-   bool save( std::ostream& file ) const;
+   String strip( char strip = ' ' ) const;
 
-   // TODO: remove
-   //! Read from binary file
-   bool load( std::istream& file );
+   //! Split the string into list of strings w.r.t. given separator.
+   int split( Containers::List< String >& list, const char separator = ' ' ) const;
 
    //! Write to a binary file
    bool save( File& file ) const;
@@ -146,15 +146,14 @@ class String
    //! Read one line from given stream.
    bool getLine( std::istream& stream );
 
-   //! Parse the string into list of strings w.r.t. given separator.
-   int parse( List< String >& list, const char separator = ' ' ) const;
-
-   friend std::ostream& operator << ( std::ostream& stream, const String& str );
+   friend std::ostream& operator<<( std::ostream& stream, const String& str );
 };
 
-String operator + ( const char* string1, const String& string2 );
+String operator+( char string1, const String& string2 );
+
+String operator+( const char* string1, const String& string2 );
 
-std::ostream& operator << ( std::ostream& stream, const String& str );
+std::ostream& operator<<( std::ostream& stream, const String& str );
 
 template< typename T >
 String convertToString( const T& value )
diff --git a/src/TNL/SystemInfo.cpp b/src/TNL/SystemInfo.cpp
deleted file mode 100644
index bbc23b5e211d3a96a1be1eeb081268acdd9ad43f..0000000000000000000000000000000000000000
--- a/src/TNL/SystemInfo.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-#include <set>
-#include <iomanip>
-#include <cstring>
-#include <ctime>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "SystemInfo.h"
-
-namespace TNL {
-
-SystemInfo::SystemInfo()
-{
-   uname( &uts );
-   parseCPUInfo();
-}
-
-void
-SystemInfo::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();
-}
-
-String
-SystemInfo::getHostname( void ) const
-{
-   char host_name[ 256 ];
-   gethostname( host_name, 255 );
-   return String( host_name );
-}
-
-String
-SystemInfo::getArchitecture( void ) const
-{
-   return String( uts.machine );
-}
-
-String
-SystemInfo::getSystemName( void ) const
-{
-   return String( uts.sysname );
-}
-
-String
-SystemInfo::getSystemRelease( void ) const
-{
-   return String( uts.release );
-}
-
-String
-SystemInfo::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 String( ss.str().c_str() );
-   char buffer[1024];
-   std::strftime( buffer, 1024, format, localtime );
-   return String( buffer );
-}
-
-int
-SystemInfo::getNumberOfProcessors( void ) const
-{
-   return numberOfProcessors;
-}
-
-String
-SystemInfo::getOnlineCPUs( void ) const
-{
-   std::string online = readFile< std::string >( "/sys/devices/system/cpu/online" );
-   return String( online.c_str() );
-}
-
-int
-SystemInfo::getNumberOfCores( int cpu_id ) const
-{
-   return CPUCores;
-}
-
-int
-SystemInfo::getNumberOfThreads( int cpu_id ) const
-{
-   return CPUThreads;
-}
-
-String
-SystemInfo::getCPUModelName( int cpu_id ) const
-{
-   return CPUModelName;
-}
-
-int
-SystemInfo::getCPUMaxFrequency( int cpu_id ) const
-{
-   String fileName( "/sys/devices/system/cpu/cpu" );
-   fileName += String( cpu_id ) + "/cpufreq/cpuinfo_max_freq";
-   return readFile< int >( fileName );
-}
-
-tnlCacheSizes
-SystemInfo::getCPUCacheSizes( int cpu_id ) const
-{
-   String directory( "/sys/devices/system/cpu/cpu" );
-   directory += String( cpu_id ) + "/cache";
-
-   tnlCacheSizes sizes;
-   for( int i = 0; i <= 3; i++ ) {
-      const String cache = directory + "/index" + String( 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;
-}
-
-} // namespace TNL
diff --git a/src/TNL/SystemInfo.h b/src/TNL/SystemInfo.h
deleted file mode 100644
index 6d0ce5cd9941d4431b209b5e47feb821620daee9..0000000000000000000000000000000000000000
--- a/src/TNL/SystemInfo.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-#include <fstream>
-#include <sstream>
-
-#include <sys/utsname.h>
-
-#include <TNL/String.h>
-
-namespace TNL {
-
-// TODO: Move this to Devices::Host
-struct tnlCacheSizes {
-   int L1instruction = 0;
-   int L1data = 0;
-   int L2 = 0;
-   int L3 = 0;
-};
-
-class SystemInfo
-{
-public:
-   SystemInfo();
-
-   String getHostname( void ) const;
-   String getArchitecture( void ) const;
-   String getSystemName( void ) const;
-   String getSystemRelease( void ) const;
-   String getCurrentTime( const char* format = "%a %b %d %Y, %H:%M:%S" ) const;
-
-   int getNumberOfProcessors( void ) const;
-   String getOnlineCPUs( void ) const;
-   int getNumberOfCores( int cpu_id ) const;
-   int getNumberOfThreads( int cpu_id ) const;
-   String getCPUModelName( int cpu_id ) const;
-   int getCPUMaxFrequency( int cpu_id ) const;
-   tnlCacheSizes getCPUCacheSizes( int cpu_id ) const;
-
-protected:
-   struct utsname uts;
-   int numberOfProcessors = 0;
-   String CPUModelName;
-   int CPUThreads = 0;
-   int CPUCores = 0;
-
-   void parseCPUInfo( void );
-
-   template< typename ResultType >
-   ResultType
-   readFile( const String & 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;
-   }
-};
-
-} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Timer.cpp b/src/TNL/Timer.cpp
index 06a50358017c631b9710d5e88b1fd093e43fc4a3..dc561202e7f6f7b759cc599edba7e37d2a1b7362 100644
--- a/src/TNL/Timer.cpp
+++ b/src/TNL/Timer.cpp
@@ -9,6 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include <TNL/Timer.h>
+#include <TNL/Logger.h>
 
 #include <TNL/tnlConfig.h>
 #ifdef HAVE_SYS_RESOURCE_H
diff --git a/src/TNL/Timer.h b/src/TNL/Timer.h
index 58e35e03d1636178ac6907ade662b8217447639a..5019ab46f3bf2ff0dcef2bed65d96ac9af848457 100644
--- a/src/TNL/Timer.h
+++ b/src/TNL/Timer.h
@@ -11,10 +11,10 @@
 
 #pragma once
 
-#include <TNL/Logger.h>
-
 namespace TNL {
 
+class Logger;
+
 class Timer
 {
    public:
diff --git a/src/TNL/UniquePointer.h b/src/TNL/UniquePointer.h
index 82e0ff11f5d832099c0def3155bc0f07f2b2521e..606f86cc4326c57cd73f7efa525dbcc4b344306b 100644
--- a/src/TNL/UniquePointer.h
+++ b/src/TNL/UniquePointer.h
@@ -1,20 +1,15 @@
-/***************************************************************************
- *                                                                         *
- *   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.                                   *
- *                                                                         *
- ***************************************************************************/
-
 /***************************************************************************
                           UniquePointer.h  -  description
                              -------------------
     begin                : May 6, 2016
-    copyright            : (C) 2016 by Tomas Oberhuber
+    copyright            : (C) 2016 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber, Jakub Klinkovsky
+
 #pragma once
 
 #include <TNL/Devices/Host.h>
@@ -23,6 +18,8 @@
 
 #include <cstring>
 
+#include "Devices/MIC.h"
+
 
 namespace TNL { 
 
@@ -66,11 +63,18 @@ class UniquePointer< Object, Devices::Host > : public SmartPointer
          return *( this->pointer );
       }
       
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pointer;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pointer;
+      }
+
       template< typename Device = Devices::Host >
       const Object& getData() const
       {
@@ -153,17 +157,24 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
          return this->pd->data;
       }
       
-      operator bool()
+      __cuda_callable__
+      operator bool() const
       {
          return this->pd;
       }
 
+      __cuda_callable__
+      bool operator!() const
+      {
+         return ! this->pd;
+      }
+
       template< typename Device = Devices::Host >      
       const Object& getData() const
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
             return this->pd->data;
          if( std::is_same< Device, Devices::Cuda >::value )
@@ -174,8 +185,8 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
       Object& modifyData()
       {
          static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
-         Assert( this->pd, );
-         Assert( this->cuda_pointer, );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->cuda_pointer, );
          if( std::is_same< Device, Devices::Host >::value )
          {
             this->pd->maybe_modified = true;
@@ -208,7 +219,7 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
          if( this->modified() )
          {
             cudaMemcpy( (void*) this->cuda_pointer, (void*) &this->pd->data, sizeof( Object ), cudaMemcpyHostToDevice );
-            if( ! checkCudaDevice )
+            if( ! TNL_CHECK_CUDA_DEVICE )
                return false;
             this->set_last_sync_state();
             return true;
@@ -244,12 +255,8 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
       bool allocate( Args... args )
       {
          this->pd = new PointerData( args... );
-         if( ! this->pd )
-            return false;
          // pass to device
          this->cuda_pointer = Devices::Cuda::passToDevice( this->pd->data );
-         if( ! this->cuda_pointer )
-            return false;
          // set last-sync state
          this->set_last_sync_state();
          Devices::Cuda::insertSmartPointer( this );
@@ -258,14 +265,14 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
 
       void set_last_sync_state()
       {
-         Assert( this->pd, );
+         TNL_ASSERT( this->pd, );
          std::memcpy( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( ObjectType ) );
          this->pd->maybe_modified = false;
       }
 
       bool modified()
       {
-         Assert( this->pd, );
+         TNL_ASSERT( this->pd, );
          // optimization: skip bitwise comparison if we're sure that the data is the same
          if( ! this->pd->maybe_modified )
             return false;
@@ -287,5 +294,194 @@ class UniquePointer< Object, Devices::Cuda > : public SmartPointer
       Object* cuda_pointer;
 };
 
+#ifdef HAVE_MIC
+template< typename Object >
+class UniquePointer< Object, Devices::MIC > : public SmartPointer
+{
+   public:
+      
+      typedef Object ObjectType;
+      typedef Devices::MIC DeviceType;
+      typedef UniquePointer< Object, Devices::MIC > ThisType;
+         
+      template< typename... Args >
+      explicit  UniquePointer( const Args... args )
+      : pd( nullptr ),
+        cuda_pointer( nullptr )
+      {
+         this->allocate( args... );
+      }
+      
+      const Object* operator->() const
+      {
+         return &this->pd->data;
+      }
+      
+      Object* operator->()
+      {
+         this->pd->maybe_modified = true;
+         return &this->pd->data;
+      }
+      
+      const Object& operator *() const
+      {
+         return this->pd->data;
+      }
+      
+      Object& operator *()
+      {
+         this->pd->maybe_modified = true;
+         return this->pd->data;
+      }
+      
+      operator bool()
+      {
+         return this->pd;
+      }
+
+      template< typename Device = Devices::Host >      
+      const Object& getData() const
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+            return this->pd->data;
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );            
+      }
+
+      template< typename Device = Devices::Host >
+      Object& modifyData()
+      {
+         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::MIC >::value, "Only Devices::Host or Devices::MIC devices are accepted here." );
+         TNL_ASSERT( this->pd, );
+         TNL_ASSERT( this->mic_pointer, );
+         if( std::is_same< Device, Devices::Host >::value )
+         {
+            this->pd->maybe_modified = true;
+            return this->pd->data;
+         }
+         if( std::is_same< Device, Devices::MIC >::value )
+            return *( this->mic_pointer );
+      }
+      
+      const ThisType& operator=( ThisType& ptr )
+      {
+         this->free();
+         this->pd = ptr.pd;
+         this->mic_pointer = ptr.mic_pointer;
+         ptr.pd = nullptr;
+         ptr.mic_pointer = nullptr;
+         return *this;
+      }
+      
+      const ThisType& operator=( ThisType&& ptr )
+      {
+         return this->operator=( ptr );
+      }      
+      
+      bool synchronize()
+      {
+         if( ! this->pd )
+            return true;
+         if( this->modified() )
+         { 
+            Devices::MIC::CopyToMIC(this->mic_pointer,(void*) &this->pd->data,sizeof(Object));  
+            this->set_last_sync_state();
+            return true;
+         }
+         return true;//??
+      }
+            
+      ~UniquePointer()
+      {
+         this->free();
+         Devices::MIC::removeSmartPointer( this );
+      }
+      
+   protected:
+
+      struct PointerData
+      {
+         Object data;
+         char data_image[ sizeof(Object) ];
+         bool maybe_modified;
+
+         template< typename... Args >
+         explicit PointerData( Args... args )
+         : data( args... ),
+           maybe_modified( false )
+         {}
+      };
+
+      template< typename... Args >
+      bool allocate( Args... args )
+      {
+         this->pd = new PointerData( args... );
+         if( ! this->pd )
+            return false;
+         // pass to device
+         this->mic_pointer=(Object*)Devices::MIC::AllocMIC(sizeof(Object));
+         if( ! this->mic_pointer )
+            return false;
+         Devices::MIC::CopyToMIC((void*)mic_pointer,(void*)&this->pd->data,sizeof(Object));
+         // set last-sync state
+         this->set_last_sync_state();
+         Devices::MIC::insertSmartPointer( this );
+         return true;
+      }
+
+      void set_last_sync_state()
+      {
+         TNL_ASSERT( this->pd, );
+         std::memcpy( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( ObjectType ) );
+         this->pd->maybe_modified = false;
+      }
+
+      bool modified()
+      {
+         TNL_ASSERT( this->pd, );
+         // optimization: skip bitwise comparison if we're sure that the data is the same
+         if( ! this->pd->maybe_modified )
+            return false;
+         return std::memcmp( (void*) &this->pd->data_image, (void*) &this->pd->data, sizeof( ObjectType ) ) != 0;
+      }
+
+      void free()
+      {
+         if( this->pd )
+            delete this->pd;
+         if( this->mic_pointer )
+             Devices::MIC::FreeMIC(mic_pointer);
+      }
+      
+      PointerData* pd;
+
+      // cuda_pointer can't be part of PointerData structure, since we would be
+      // unable to dereference this-pd on the device
+      Object* mic_pointer;
+};
+#endif
+
+#if  (!defined(NDEBUG)) && (!defined(HAVE_MIC)) 
+namespace Assert {
+
+template< typename Object, typename Device >
+struct Formatter< UniquePointer< Object, Device > >
+{
+   static std::string
+   printToString( const UniquePointer< Object, Device >& value )
+   {
+      ::std::stringstream ss;
+      ss << "(UniquePointer< " << Object::getType() << ", " << Device::getDeviceType()
+         << " > object at " << &value << ")";
+      return ss.str();
+   }
+};
+
+} // namespace Assert
+#endif
+
 } // namespace TNL
 
diff --git a/src/TNL/core/CMakeLists.txt b/src/TNL/core/CMakeLists.txt
deleted file mode 100755
index 88d96b42eb1c3e38a03cf8c352623d625d1fbfc0..0000000000000000000000000000000000000000
--- a/src/TNL/core/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-set (headers 
-             tnlConstants.h
-             tnlIndexedSet.h
-             mfilename.h 
-             mfuncs.h 
-             mpi-supp.h 
-             param-types.h )
-
-SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/core )
-set( common_SOURCES
-     ${CURRENT_DIR}/mfilename.cpp 
-     ${CURRENT_DIR}/mpi-supp.cpp )
-
-IF( BUILD_CUDA )
-   set( tnl_core_CUDA__SOURCES
-        ${tnl_core_arrays_CUDA__SOURCES}
-        ${tnl_core_containers_CUDA__SOURCES}
-        ${tnl_core_cuda_CUDA__SOURCES}
-        ${tnl_core_vectors_CUDA__SOURCES}
-        ${tnl_core_images_CUDA__SOURCES}
-        ${common_SOURCES} 
-        PARENT_SCOPE )
-ENDIF()    
-
-set( tnl_core_SOURCES     
-     ${tnl_core_arrays_SOURCES}
-     ${tnl_core_containers_SOURCES}
-     ${tnl_core_cuda_SOURCES}
-     ${tnl_core_vectors_SOURCES}
-     ${tnl_core_images_SOURCES}
-     ${common_SOURCES}
-     PARENT_SCOPE )
-    
-
-#SET( libtnlcoreincludedir ${TNL_INCLUDE_DIR}/core )
-#SET( libtnlcoreinclude_HEADERS ${headers} )
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/core )
-
-
-
diff --git a/src/TNL/legacy/CMakeLists.txt b/src/TNL/legacy/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/src/TNL/legacy/benchmarks/matrix-solvers-benchmark.h b/src/TNL/legacy/benchmarks/matrix-solvers-benchmark.h
index c3784b64e7b2e621da62b02775974bbf0ef7f68c..1bb3dfd96c4d807af244c5f3424990b9278f1824 100644
--- a/src/TNL/legacy/benchmarks/matrix-solvers-benchmark.h
+++ b/src/TNL/legacy/benchmarks/matrix-solvers-benchmark.h
@@ -15,6 +15,7 @@
 #include <TNL/File.h>
 #include <TNL/Object.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Config/ParameterContainer.h>
 #include <TNL/Matrices/CSR.h>
@@ -78,11 +79,7 @@ bool benchmarkSolver( const Config::ParameterContainer&  parameters,
    solver. setSolverMonitor( solverMonitor );
    solver. setRefreshRate( 10 );
    solverMonitor. resetTimers();
-#ifdef HAVE_NOT_CXX11
-   solver. template solve< Vector, LinearResidueGetter< Matrix, Vector > >( b, x );
-#else
    solver. solve( b, x );
-#endif
 
    bool solverConverged( solver. getResidue() < maxResidue );
    const String& logFileName = parameters. getParameter< String >( "log-file" );
@@ -313,8 +310,7 @@ bool benchmarkMatrix( const Config::ParameterContainer&  parameters )
          return false;
       x = cudaX;*/
 #else
-      CudaSupportMissingMessage;;
-      return false;
+      throw Exceptions::CudaSupportMissing();
 #endif
    }
 
@@ -357,7 +353,7 @@ int main( int argc, char* argv[] )
       std::cerr << "Unable to detect object type in " << inputFile << std::endl;
       return EXIT_FAILURE;
    }
-   List< String > parsedObjectType;
+   Containers::List< String > parsedObjectType;
    parseObjectType( objectType,
                     parsedObjectType );
    String objectClass = parsedObjectType[ 0 ];
diff --git a/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h b/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
index 767e9404e2215221742a2d3ba8c9d33902e5b3bb..35a5b388c9b317d3fbf4292337814b76d6d7122b 100644
--- a/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
+++ b/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
@@ -12,7 +12,9 @@
 #define TNLSPMVBENCHMARKADAPTIVERGCSRMATRIX_H_
 
 #include "tnlSpmvBenchmark.h"
+
 #include <TNL/Assert.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
 
 template< typename Real, typename Device, typename Index>
 class tnlSpmvBenchmarkAdaptiveRgCSR : public tnlSpmvBenchmark< Real, Device, Index, tnlAdaptiveRgCSR >
@@ -77,7 +79,7 @@ template< typename Real,
           typename Index>
 bool tnlSpmvBenchmarkAdaptiveRgCSR< Real, Device, Index > :: setup( const CSR< Real, Devices::Host, Index >& matrix )
 {
-   //Assert( this->groupSize > 0, std::cerr << "groupSize = " << this->groupSize );
+   //TNL_ASSERT( this->groupSize > 0, std::cerr << "groupSize = " << this->groupSize );
    if( Device :: getDevice() == Devices::HostDevice )
    {
       this->matrix. tuneFormat( desiredChunkSize, cudaBlockSize );
@@ -131,7 +133,7 @@ void tnlSpmvBenchmarkAdaptiveRgCSR< Real, Device, Index > :: writeProgress() con
        std::cout << right << std::setw( this->benchmarkStatusColumnWidth ) << "  FAILED";
 #ifndef HAVE_CUDA
    if( Device :: getDevice() == Devices::CudaDevice )
-      CudaSupportMissingMessage;;
+      throw Exceptions::CudaSupportMissing();
 #endif
      std::cout << std::endl;
 }
diff --git a/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h b/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
index e8b04c87073bdc35c2cc45ff65571be53affbfe4..6327ac95d659ebc6592d458f27288a11cf34d141 100644
--- a/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
+++ b/src/TNL/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
@@ -13,6 +13,8 @@
 
 #include "tnlSpmvBenchmark.h"
 
+#include <TNL/Exceptions/CudaSupportMissing.h>
+
 template< typename Real, typename Device, typename Index>
 class tnlSpmvBenchmarkRgCSR : public tnlSpmvBenchmark< Real, Device, Index, tnlRgCSR >
 {
@@ -69,7 +71,7 @@ template< typename Real,
           typename Index>
 bool tnlSpmvBenchmarkRgCSR< Real, Device, Index > :: setup( const CSR< Real, Devices::Host, Index >& csrMatrix )
 {
-   Assert( this->groupSize > 0, std::cerr << "groupSize = " << this->groupSize );
+   TNL_ASSERT( this->groupSize > 0, std::cerr << "groupSize = " << this->groupSize );
    if( Device :: getDevice() == Devices::HostDevice )
    {
       this->matrix. tuneFormat( groupSize,
@@ -134,7 +136,7 @@ void tnlSpmvBenchmarkRgCSR< Real, Device, Index > :: writeProgress() const
        std::cout << right << std::setw( this->benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this->maxError << ". ";
 #ifndef HAVE_CUDA
    if( Device :: getDevice() == Devices::CudaDevice )
-      CudaSupportMissingMessage;;
+      throw Exceptions::CudaSupportMissing();
 #endif
      std::cout << std::endl;
 }
diff --git a/src/TNL/legacy/mesh/tnlDistributedGrid.h b/src/TNL/legacy/mesh/tnlDistributedGrid.h
index b6d0b718dff4924ab92e78484b13d1bd3083e3ec..6cdc286e9535c54e19a47e92cae58e286d6feaca 100644
--- a/src/TNL/legacy/mesh/tnlDistributedGrid.h
+++ b/src/TNL/legacy/mesh/tnlDistributedGrid.h
@@ -14,7 +14,7 @@
 #include <TNL/Object.h>
 #include <TNL/tnlCommunicator.h>
 
-template< int Dimensions,
+template< int Dimension,
           typename GridType,
           typename Device = Devices::Host,
           typename Real = double,
@@ -25,7 +25,7 @@ class tnlDistributedGrid : public Object
    tnlDistributedGrid();
 
    //! We do not allow copy constructor without object name.
-   tnlDistributedGrid( const tnlDistributedGrid< Dimensions, Real, Device, Index >& a );
+   tnlDistributedGrid( const tnlDistributedGrid< Dimension, Real, Device, Index >& a );
 
    public:
 
@@ -33,29 +33,29 @@ class tnlDistributedGrid : public Object
 
    bool init( tnlCommunicator* communicator,
               const GridType& grid,
-              const StaticVector< Dimensions, Index >& subdomainOverlaps );
+              const StaticVector< Dimension, Index >& subdomainOverlaps );
 
    tnlCommunicator< Device >* getCommunicator() const;
 
-   const StaticVector< Dimensions, Real >& getDomainLowerCorner() const;
+   const StaticVector< Dimension, Real >& getDomainLowerCorner() const;
 
-   const StaticVector< Dimensions, Real >& getDomainUpperCorner() const;
+   const StaticVector< Dimension, Real >& getDomainUpperCorner() const;
 
-   const StaticVector< Dimensions, Index >& getDimensions() const;
+   const StaticVector< Dimension, Index >& getDimensions() const;
 
-   const StaticVector< Dimensions, int >& getGridDimensions() const;
+   const StaticVector< Dimension, int >& getGridDimensions() const;
 
-   const StaticVector< Dimensions, int >& getLowerNeighbors() const;
+   const StaticVector< Dimension, int >& getLowerNeighbors() const;
 
-   const StaticVector< Dimensions, Index >& getLowerSubdomainsOverlaps() const;
+   const StaticVector< Dimension, Index >& getLowerSubdomainsOverlaps() const;
 
-   const StaticVector< Dimensions, int >& getNodeCoordinates() const;
+   const StaticVector< Dimension, int >& getNodeCoordinates() const;
 
-   const StaticVector< Dimensions, Index >& getSubdomainDimensions() const;
+   const StaticVector< Dimension, Index >& getSubdomainDimensions() const;
 
-   const StaticVector< Dimensions, Index >& getUpperSubdomainsOverlaps() const;
+   const StaticVector< Dimension, Index >& getUpperSubdomainsOverlaps() const;
 
-   const StaticVector< Dimensions, int >& getUppperNeighbors() const;
+   const StaticVector< Dimension, int >& getUppperNeighbors() const;
 
    protected:
 
@@ -66,39 +66,39 @@ class tnlDistributedGrid : public Object
    /*!***
     * This is naturally generalized to more dimensions.
     */
-   StaticVector< Dimensions, Real > domainLowerCorner;
+   StaticVector< Dimension, Real > domainLowerCorner;
 
    //! In 2D this is the right top corner of the global domain.
    /*!***
     * This is naturally generalized to more dimensions.
     */
-   StaticVector< Dimensions, Real > domainUpperCorner;
+   StaticVector< Dimension, Real > domainUpperCorner;
 
-   //! Dimensions of the global domain.
-   StaticVector< Dimensions, Index > globalDimensions;
+   //! Dimension of the global domain.
+   StaticVector< Dimension, Index > globalDimensions;
 
-   //! Dimensions of the local subdomain.
-   StaticVector< Dimensions, Index > subdomainDimensions;
+   //! Dimension of the local subdomain.
+   StaticVector< Dimension, Index > subdomainDimensions;
 
    //! Number of the distributed grid nodes along each dimension.
-   StaticVector< Dimensions, int > gridDimensions;
+   StaticVector< Dimension, int > gridDimensions;
 
    //! Coordinates of this node of the distributed grid.
-   StaticVector< Dimensions, int > nodeCoordinates;
+   StaticVector< Dimension, int > nodeCoordinates;
 
    //! Here are device IDs taken from the tnlCommunicator.
    /*!***
     * In 2D, this is the device ID of the neighbor on the
     * right and above.
     */
-   StaticVector< Dimensions, int > uppperNeighbors;
+   StaticVector< Dimension, int > uppperNeighbors;
 
    //! Here are device IDs taken from the tnlCommunicator.
    /*!***
     * In 2D, this is the device ID of the neighbor on the
     * left and below.
     */
-   StaticVector< Dimensions, int > lowerNeighbors;
+   StaticVector< Dimension, int > lowerNeighbors;
 
    //! Here are widths of overlaps at subdomain boundaries with neighbors.
    /*!***
@@ -106,7 +106,7 @@ class tnlDistributedGrid : public Object
     * between neighboring nodes. In 2D, here are overlaps
     * with the neighbors on the right and above.
     */
-   StaticVector< Dimensions, Index > upperSubdomainsOverlaps;
+   StaticVector< Dimension, Index > upperSubdomainsOverlaps;
 
    //! Here are widths of overlaps at subdomain boundaries with neighbors.
    /*!***
@@ -114,88 +114,88 @@ class tnlDistributedGrid : public Object
     * between neighboring nodes. In 2D, here are overlaps
     * with the neighbors on the left and below.
     */
-   StaticVector< Dimensions, Index > lowerSubdomainsOverlaps;
+   StaticVector< Dimension, Index > lowerSubdomainsOverlaps;
 
 };
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: tnlDistributedGrid( const String& name )
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: tnlDistributedGrid( const String& name )
  : Object( name )
 {
 
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-bool tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: init( tnlCommunicator* communicator,
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+bool tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: init( tnlCommunicator* communicator,
                                                                               const GridType& grid,
-                                                                              const StaticVector< Dimensions, int >& gridDimensions,
-                                                                              const StaticVector< Dimensions, Index >& subdomainOverlaps )
+                                                                              const StaticVector< Dimension, int >& gridDimensions,
+                                                                              const StaticVector< Dimension, Index >& subdomainOverlaps )
 {
 
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-tnlCommunicator* tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getCommunicator() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+tnlCommunicator* tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getCommunicator() const
 {
     return communicator;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Real >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getDomainLowerCorner() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Real >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getDomainLowerCorner() const
 {
     return domainLowerCorner;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Real >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getDomainUpperCorner() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Real >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getDomainUpperCorner() const
 {
     return domainUpperCorner;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Index >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getDimensions() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Index >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getDimensions() const
 {
     return globalDimensions;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, int >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getGridDimensions() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, int >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getGridDimensions() const
 {
     return gridDimensions;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, int >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getLowerNeighbors() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, int >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getLowerNeighbors() const
 {
     return lowerNeighbors;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Index >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getLowerSubdomainsOverlaps() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Index >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getLowerSubdomainsOverlaps() const
 {
     return lowerSubdomainsOverlaps;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, int >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getNodeCoordinates() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, int >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getNodeCoordinates() const
 {
     return nodeCoordinates;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Index >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getSubdomainDimensions() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Index >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getSubdomainDimensions() const
 {
     return subdomainDimensions;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, Index >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getUpperSubdomainsOverlaps() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, Index >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getUpperSubdomainsOverlaps() const
 {
     return upperSubdomainsOverlaps;
 }
 
-template< int Dimensions, typename GridType, typename Device, typename Real, typename Index >
-const StaticVector< Dimensions, int >& tnlDistributedGrid< Dimensions, GridType, Device, Real, Index > :: getUppperNeighbors() const
+template< int Dimension, typename GridType, typename Device, typename Real, typename Index >
+const StaticVector< Dimension, int >& tnlDistributedGrid< Dimension, GridType, Device, Real, Index > :: getUppperNeighbors() const
 {
     return uppperNeighbors;
 }
diff --git a/src/TNL/legacy/tnl-benchmarks.h b/src/TNL/legacy/tnl-benchmarks.h
index 5e97a98bd32ac6f11cb3d0b7ed757e0d2520570a..df9af1cf43231d36e5460cd410b3c7756529ada9 100644
--- a/src/TNL/legacy/tnl-benchmarks.h
+++ b/src/TNL/legacy/tnl-benchmarks.h
@@ -93,7 +93,7 @@ void tnlCPUReductionMin( const Vector< T >& host_vector,
 {
    const T* data = host_vector. Data();
    const int size = host_vector. GetSize();
-   //Assert( data );
+   //TNL_ASSERT( data );
    min = data[ 0 ];
    for( int i = 1; i < size; i ++ )
       min = :: min( min,  data[ i ] );
@@ -105,7 +105,7 @@ void tnlCPUReductionMax( const Vector< T >& host_vector,
 {
    const T* data = host_vector. Data();
    const int size = host_vector. GetSize();
-   //Assert( data );
+   //TNL_ASSERT( data );
    max = data[ 0 ];
    for( int i = 1; i < size; i ++ )
       max = :: max( max,  data[ i ] );
diff --git a/src/TNL/param-types.h b/src/TNL/param-types.h
index 790cf627abc0c58094e3113b664019130d53e825..8a13e09565dd3ede7c2414c9504b0e12ab142a5d 100644
--- a/src/TNL/param-types.h
+++ b/src/TNL/param-types.h
@@ -16,7 +16,7 @@
 namespace TNL {
 
 template< typename T >
-String getType() { return T :: getType(); };
+String getType() { return T::getType(); };
 
 template<> inline String getType< bool >() { return String( "bool" ); };
 template<> inline String getType< short int >() { return String( "short int" ); };
diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt
old mode 100755
new mode 100644
index 3934359e9ba8448dc0fdf69bddac7a3101eb70ab..7069abf67277eda2f4d77835c868d166482715b3
--- a/src/Tools/CMakeLists.txt
+++ b/src/Tools/CMakeLists.txt
@@ -56,12 +56,7 @@ ADD_EXECUTABLE(tnl-curve2gnuplot${debugExt} ${tnlcurve2gnuplotsources})
 target_link_libraries (tnl-curve2gnuplot${debugExt} tnl${debugExt}-${tnlVersion} )
 
 IF( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnl-cuda-arch${debugExt} tnl-cuda-arch.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
-    SET_TARGET_PROPERTIES( tnl-cuda-arch${debugExt} PROPERTIES CUDA_COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )
-ENDIF()
-         
-IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnl-cuda-arch${debugExt} tnl-cuda-arch.cu )
    INSTALL( TARGETS tnl-cuda-arch${debugExt}
             RUNTIME DESTINATION bin
             PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
diff --git a/src/Tools/python-path-test.py b/src/Tools/python-path-test.py
deleted file mode 100644
index 27ac980f994367b58d182385da864695a0b3aa18..0000000000000000000000000000000000000000
--- a/src/Tools/python-path-test.py
+++ /dev/null
@@ -1,3 +0,0 @@
-import TNL
-
-print( "OK" )
diff --git a/src/Tools/src/CMakeLists.txt b/src/Tools/src/CMakeLists.txt
deleted file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/Tools/tnl-compile.in b/src/Tools/tnl-compile.in
index 62dd15771afa36e3ccf44468f14644929bce4405..bf196432c86c188f1f5ac7a5dcc9532af478c8f0 100644
--- a/src/Tools/tnl-compile.in
+++ b/src/Tools/tnl-compile.in
@@ -13,3 +13,4 @@ do
 done
 
 echo -I@CMAKE_INSTALL_PREFIX@/include/tnl-@tnlVersion@ ${CUDA_FLAGS} ${CXX_STD_FLAGS} ${DEBUG_FLAGS}
+
diff --git a/src/Tools/tnl-cuda-arch.cu b/src/Tools/tnl-cuda-arch.cu
index 7f1fb17496601adc5ffc84467a9c5db25feae244..7d880a19a32b7f41bf0fd45d7949f73f8c5933e9 100644
--- a/src/Tools/tnl-cuda-arch.cu
+++ b/src/Tools/tnl-cuda-arch.cu
@@ -1,6 +1,8 @@
 #include <stdio.h> 
+#include <string.h>
 
-int main() {
+int main( int argc, char** argv )
+{
     int num_devices = 0;
     cudaError_t error_id = cudaGetDeviceCount( &num_devices );
 
@@ -21,8 +23,15 @@ int main() {
 
             if( i > 0 )
                 printf(" ");
-            printf( "-gencode arch=compute_%d%d,code=sm_%d%d",
-                    prop.major, compute_minor, prop.major, prop.minor );
+
+            if( argc == 2 && strcmp( argv[1], "--clang" ) == 0 ) {
+                printf( "--cuda-gpu-arch=sm_%d%d",
+                        prop.major, prop.minor );
+            }
+            else {
+                printf( "-gencode arch=compute_%d%d,code=sm_%d%d",
+                        prop.major, compute_minor, prop.major, prop.minor );
+            }
     }
     printf("\n");
 }
diff --git a/src/Tools/tnl-dicom-reader.cpp b/src/Tools/tnl-dicom-reader.cpp
index f7e3ba24322a139d6556eafb7fbc498e354e3f2c..5b38b123092ccadf5c1d0fab1df842e7d258640a 100644
--- a/src/Tools/tnl-dicom-reader.cpp
+++ b/src/Tools/tnl-dicom-reader.cpp
@@ -38,7 +38,7 @@ bool processDicomFiles( const Config::ParameterContainer& parameters )
 
 bool processDicomSeries( const Config::ParameterContainer& parameters )
 {
-   const List< String >& dicomSeriesNames = parameters.getParameter< List< String > >( "dicom-series" );
+   const Containers::List< String >& dicomSeriesNames = parameters.getParameter< Containers::List< String > >( "dicom-series" );
    String meshFile = parameters.getParameter< String >( "mesh-file" );
    bool verbose = parameters.getParameter< bool >( "verbose" );
 
diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp
index 3e1155ce722d0c40142e99889addbc26365b6c56..013f7bf21a2218f940a037ca94e39709a14b0505 100644
--- a/src/Tools/tnl-diff.cpp
+++ b/src/Tools/tnl-diff.cpp
@@ -15,7 +15,7 @@
 void setupConfig( Config::ConfigDescription& config )
 {
    config.addEntry< String >( "mesh", "Input mesh file.", "mesh.tnl" );
-   config.addRequiredEntry< List< String > >( "input-files", "The first set of the input files." );
+   config.addRequiredEntry< Containers::List< String > >( "input-files", "The first set of the input files." );
    config.addEntry< String >( "output-file", "File for the output data.", "tnl-diff.log" );
    config.addEntry< String >( "mode", "Mode 'couples' compares two subsequent files. Mode 'sequence' compares the input files against the first one. 'halves' compares the files from the and the second half of the intput files.", "couples" );
       config.addEntryEnum< String >( "couples" );
@@ -56,11 +56,11 @@ int main( int argc, char* argv[] )
       return EXIT_FAILURE;
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
-   List< String > parsedMeshType;
+   Containers::List< String > parsedMeshType;
    if( ! parseObjectType( meshType, parsedMeshType ) )
    {
       std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl;
-      return false;
+      return EXIT_FAILURE;
    }
    if( parsedMeshType[ 0 ] == "Meshes::Grid" ||
        parsedMeshType[ 0 ] == "tnlGrid" )        // TODO: remove deprecated type name
diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h
index 0d6e1a0f7b2012093e90bc03244c88b1c3770468..66f707593154e63bcb9b2362c83fe40646fbb28a 100644
--- a/src/Tools/tnl-diff.h
+++ b/src/Tools/tnl-diff.h
@@ -24,7 +24,7 @@ template< typename MeshPointer, typename Element, typename Real, typename Index
 bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters )
 {
    bool verbose = parameters. getParameter< bool >( "verbose" );
-   List< String > inputFiles = parameters. getParameter< List< String > >( "input-files" );
+   Containers::List< String > inputFiles = parameters. getParameter< Containers::List< String > >( "input-files" );
    String mode = parameters. getParameter< String >( "mode" );
    String outputFileName = parameters. getParameter< String >( "output-file" );
    double snapshotPeriod = parameters. getParameter< double >( "snapshot-period" );
@@ -50,7 +50,7 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con
       std::cout << std::endl;
    
    typedef typename MeshPointer::ObjectType Mesh;
-   Functions::MeshFunction< Mesh, Mesh::getMeshDimensions(), Real > v1( meshPointer ), v2( meshPointer ), diff( meshPointer );
+   Functions::MeshFunction< Mesh, Mesh::getMeshDimension(), Real > v1( meshPointer ), v2( meshPointer ), diff( meshPointer );
    Real totalL1Diff( 0.0 ), totalL2Diff( 0.0 ), totalMaxDiff( 0.0 );
    for( int i = 0; i < inputFiles. getSize(); i ++ )
    {
@@ -161,7 +161,7 @@ template< typename MeshPointer, typename Element, typename Real, typename Index
 bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters )
 {
    bool verbose = parameters. getParameter< bool >( "verbose" );
-   List< String > inputFiles = parameters. getParameter< List< String > >( "input-files" );
+   Containers::List< String > inputFiles = parameters. getParameter< Containers::List< String > >( "input-files" );
    String mode = parameters. getParameter< String >( "mode" );
    String outputFileName = parameters. getParameter< String >( "output-file" );
    double snapshotPeriod = parameters. getParameter< double >( "snapshot-period" );
@@ -307,7 +307,7 @@ bool computeDifference( const MeshPointer& meshPointer, const String& objectType
 template< typename MeshPointer, typename Element, typename Real >
 bool setIndexType( const MeshPointer& meshPointer,
                    const String& inputFileName,
-                   const List< String >& parsedObjectType,
+                   const Containers::List< String >& parsedObjectType,
                    const Config::ParameterContainer& parameters )
 {
    String indexType;
@@ -335,8 +335,8 @@ bool setIndexType( const MeshPointer& meshPointer,
 template< typename MeshPointer >
 bool setTupleType( const MeshPointer& meshPointer,
                    const String& inputFileName,
-                   const List< String >& parsedObjectType,
-                   const List< String >& parsedElementType,
+                   const Containers::List< String >& parsedObjectType,
+                   const Containers::List< String >& parsedElementType,
                    const Config::ParameterContainer& parameters )
 {
    int dimensions = atoi( parsedElementType[ 1 ].getString() );
@@ -386,7 +386,7 @@ bool setTupleType( const MeshPointer& meshPointer,
 template< typename MeshPointer >
 bool setElementType( const MeshPointer& meshPointer,
                      const String& inputFileName,
-                     const List< String >& parsedObjectType,
+                     const Containers::List< String >& parsedObjectType,
                      const Config::ParameterContainer& parameters )
 {
    String elementType;
@@ -410,13 +410,13 @@ bool setElementType( const MeshPointer& meshPointer,
       return setIndexType< MeshPointer, double, double >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( elementType == "long double" )
       return setIndexType< MeshPointer, long double, long double >( meshPointer, inputFileName, parsedObjectType, parameters );
-   List< String > parsedElementType;
+   Containers::List< String > parsedElementType;
    if( ! parseObjectType( elementType, parsedElementType ) )
    {
       std::cerr << "Unable to parse object type " << elementType << "." << std::endl;
       return false;
    }
-   if( parsedElementType[ 0 ] == "tnlStaticVector" )
+   if( parsedElementType[ 0 ] == "Containers::StaticVector" )
       return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedElementType, parameters );
 
    std::cerr << "Unknown element type " << elementType << "." << std::endl;
@@ -427,7 +427,7 @@ template< typename Mesh >
 bool processFiles( const Config::ParameterContainer& parameters )
 {
    int verbose = parameters. getParameter< int >( "verbose");
-   List< String > inputFiles = parameters. getParameter< List< String > >( "input-files" );
+   Containers::List< String > inputFiles = parameters. getParameter< Containers::List< String > >( "input-files" );
    String& inputFile = inputFiles[ 0 ];
 
    /****
@@ -454,7 +454,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
    if( verbose )
      std::cout << objectType << " detected ... ";
 
-   List< String > parsedObjectType;
+   Containers::List< String > parsedObjectType;
    if( ! parseObjectType( objectType, parsedObjectType ) )
    {
       std::cerr << "Unable to parse object type " << objectType << "." << std::endl;
diff --git a/src/Tools/tnl-grid-setup.h b/src/Tools/tnl-grid-setup.h
index b92db8a380f464287c656ff9e088d3768395eb68..d76133e4a1e3274cc1ec1fdd6dd92c5b86548f64 100644
--- a/src/Tools/tnl-grid-setup.h
+++ b/src/Tools/tnl-grid-setup.h
@@ -31,10 +31,10 @@ bool setupGrid( const Config::ParameterContainer& parameters )
       std::cout << "Writing the grid to the file " << outputFile << " .... ";
 
       typedef Meshes::Grid< 1, RealType, Devices::Host, IndexType > GridType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       GridType grid;
-      grid.setDomain( VertexType( originX ), VertexType( proportionsX ) );
+      grid.setDomain( PointType( originX ), PointType( proportionsX ) );
       grid.setDimensions( CoordinatesType( sizeX ) );
       if( ! grid.save( outputFile ) )
       {
@@ -54,10 +54,10 @@ bool setupGrid( const Config::ParameterContainer& parameters )
      std::cout << "Writing the grid to the file " << outputFile << " .... ";
 
       typedef Meshes::Grid< 2, RealType, Devices::Host, IndexType > GridType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       GridType grid;
-      grid.setDomain( VertexType( originX, originY ), VertexType( proportionsX, proportionsY ) );
+      grid.setDomain( PointType( originX, originY ), PointType( proportionsX, proportionsY ) );
       grid.setDimensions( CoordinatesType( sizeX, sizeY ) );
       if( ! grid.save( outputFile ) )
       {
@@ -80,10 +80,10 @@ bool setupGrid( const Config::ParameterContainer& parameters )
      std::cout << "Writing the grid to the file " << outputFile << " .... ";
 
       typedef Meshes::Grid< 3, RealType, Devices::Host, IndexType > GridType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       GridType grid;
-      grid.setDomain( VertexType( originX, originY, originZ ), VertexType( proportionsX, proportionsY, proportionsZ ) );
+      grid.setDomain( PointType( originX, originY, originZ ), PointType( proportionsX, proportionsY, proportionsZ ) );
       grid.setDimensions( CoordinatesType( sizeX, sizeY, sizeZ ) );
       if( ! grid.save( outputFile ) )
       {
diff --git a/src/Tools/tnl-image-converter.cpp b/src/Tools/tnl-image-converter.cpp
index 3d8f59bc9b6365a375662a739006b1d1ce42570e..0cece9cf7836e410ff55e089568d6f0873f05692 100644
--- a/src/Tools/tnl-image-converter.cpp
+++ b/src/Tools/tnl-image-converter.cpp
@@ -37,7 +37,7 @@ void configSetup( Config::ConfigDescription& config )
 
 bool processImages( const Config::ParameterContainer& parameters )
 {
-    const List< String >& inputImages = parameters.getParameter< List< String > >( "input-images" );
+    const Containers::List< String >& inputImages = parameters.getParameter< Containers::List< String > >( "input-images" );
     String meshFile = parameters.getParameter< String >( "mesh-file" );
     bool verbose = parameters.getParameter< bool >( "verbose" );
  
@@ -133,7 +133,7 @@ bool processImages( const Config::ParameterContainer& parameters )
 
 bool processTNLFiles( const Config::ParameterContainer& parameters )
 {
-   const List< String >& inputFiles = parameters.getParameter< List< String > >( "input-files" );
+   const Containers::List< String >& inputFiles = parameters.getParameter< Containers::List< String > >( "input-files" );
    const String& imageFormat = parameters.getParameter< String >( "image-format" );
    String meshFile = parameters.getParameter< String >( "mesh-file" );
    bool verbose = parameters.getParameter< bool >( "verbose" );
diff --git a/src/Tools/tnl-init.cpp b/src/Tools/tnl-init.cpp
index e61afd2f627cbfc7f65f59e0f48d304c3167db72..f42b9ad3c9aeb02690ef4f7def74acf6c2ce3087 100644
--- a/src/Tools/tnl-init.cpp
+++ b/src/Tools/tnl-init.cpp
@@ -61,11 +61,11 @@ int main( int argc, char* argv[] )
       return EXIT_FAILURE;
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
-   List< String > parsedMeshType;
+   Containers::List< String > parsedMeshType;
    if( ! parseObjectType( meshType, parsedMeshType ) )
    {
       std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl;
-      return false;
+      return EXIT_FAILURE;
    }
    if( ! resolveMeshType( parsedMeshType, parameters ) )
       return EXIT_FAILURE;
diff --git a/src/Tools/tnl-init.h b/src/Tools/tnl-init.h
index ffe12126468cfca85bb05e4e0e4ca2585c69498c..355c553f02695d28f45c3994ef80891ead05b4cd 100644
--- a/src/Tools/tnl-init.h
+++ b/src/Tools/tnl-init.h
@@ -34,14 +34,14 @@ bool renderFunction( const Config::ParameterContainer& parameters )
    if( ! meshPointer->load( meshFile ) )
       return false;
 
-   typedef Functions::TestFunction< MeshType::meshDimensions, RealType > FunctionType;
+   typedef Functions::TestFunction< MeshType::getMeshDimension(), RealType > FunctionType;
    typedef SharedPointer< FunctionType, typename MeshType::DeviceType > FunctionPointer;
    FunctionPointer function;
    std::cout << "Setting up the function ... " << std::endl;
    if( ! function->setup( parameters, "" ) )
       return false;
    std::cout << "done." << std::endl;
-   typedef Functions::MeshFunction< MeshType, MeshType::meshDimensions > MeshFunctionType;
+   typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimension() > MeshFunctionType;
    typedef SharedPointer< MeshFunctionType, typename MeshType::DeviceType > MeshFunctionPointer;
    MeshFunctionPointer meshFunction( meshPointer );
    //if( ! discreteFunction.setSize( mesh.template getEntitiesCount< typename MeshType::Cell >() ) )
@@ -200,53 +200,53 @@ bool resolveRealType( const Config::ParameterContainer& parameters )
 }
 
 
-template< int Dimensions, typename RealType, typename IndexType >
-bool resolveMesh( const List< String >& parsedMeshType,
+template< int Dimension, typename RealType, typename IndexType >
+bool resolveMesh( const Containers::List< String >& parsedMeshType,
                   const Config::ParameterContainer& parameters )
 {
   std::cout << "+ -> Setting mesh type to " << parsedMeshType[ 0 ] << " ... " << std::endl;
    if( parsedMeshType[ 0 ] == "Meshes::Grid" ||
        parsedMeshType[ 0 ] == "tnlGrid" )  // TODO: remove deprecated type name
    {
-      typedef Meshes::Grid< Dimensions, RealType, Devices::Host, IndexType > MeshType;
+      typedef Meshes::Grid< Dimension, RealType, Devices::Host, IndexType > MeshType;
       return resolveRealType< MeshType >( parameters );
    }
    std::cerr << "Unknown mesh type." << std::endl;
    return false;
 }
 
-template< int Dimensions, typename RealType >
-bool resolveIndexType( const List< String >& parsedMeshType,
+template< int Dimension, typename RealType >
+bool resolveIndexType( const Containers::List< String >& parsedMeshType,
                        const Config::ParameterContainer& parameters )
 {
   std::cout << "+ -> Setting index type to " << parsedMeshType[ 4 ] << " ... " << std::endl;
    if( parsedMeshType[ 4 ] == "int" )
-      return resolveMesh< Dimensions, RealType, int >( parsedMeshType, parameters );
+      return resolveMesh< Dimension, RealType, int >( parsedMeshType, parameters );
 
    if( parsedMeshType[ 4 ] == "long int" )
-      return resolveMesh< Dimensions, RealType, long int >( parsedMeshType, parameters );
+      return resolveMesh< Dimension, RealType, long int >( parsedMeshType, parameters );
 
    return false;
 }
 
-template< int Dimensions >
-bool resolveRealType( const List< String >& parsedMeshType,
+template< int Dimension >
+bool resolveRealType( const Containers::List< String >& parsedMeshType,
                       const Config::ParameterContainer& parameters )
 {
   std::cout << "+ -> Setting real type to " << parsedMeshType[ 2 ] << " ... " << std::endl;
    if( parsedMeshType[ 2 ] == "float" )
-      return resolveIndexType< Dimensions, float >( parsedMeshType, parameters );
+      return resolveIndexType< Dimension, float >( parsedMeshType, parameters );
 
    if( parsedMeshType[ 2 ] == "double" )
-      return resolveIndexType< Dimensions, double >( parsedMeshType, parameters );
+      return resolveIndexType< Dimension, double >( parsedMeshType, parameters );
 
    if( parsedMeshType[ 2 ] == "long-double" )
-      return resolveIndexType< Dimensions, long double >( parsedMeshType, parameters );
+      return resolveIndexType< Dimension, long double >( parsedMeshType, parameters );
 
    return false;
 }
 
-bool resolveMeshType( const List< String >& parsedMeshType,
+bool resolveMeshType( const Containers::List< String >& parsedMeshType,
                       const Config::ParameterContainer& parameters )
 {
   std::cout << "+ -> Setting dimensions to " << parsedMeshType[ 1 ] << " ... " << std::endl;
diff --git a/src/Tools/tnl-mesh-convert.cpp b/src/Tools/tnl-mesh-convert.cpp
index 84cfd7fbaa57c10679127a365383494ac3f8dd29..d7de402bc72bc3cc84bd03452837cb7bff40833d 100644
--- a/src/Tools/tnl-mesh-convert.cpp
+++ b/src/Tools/tnl-mesh-convert.cpp
@@ -8,7 +8,7 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
 #include "tnl-mesh-convert.h"
 #endif
 #include <TNL/Config/ParameterContainer.h>
@@ -35,7 +35,7 @@ int main( int argc, char* argv[] )
       conf_desc.printUsage( argv[ 0 ] );
       return EXIT_FAILURE;
    }
-#ifndef HAVE_ICPC
+#ifndef __INTEL_COMPILER
    if( ! convertMesh( parameters ) )
       return EXIT_FAILURE;
 #endif
diff --git a/src/Tools/tnl-mesh-convert.h b/src/Tools/tnl-mesh-convert.h
index 320258f934fc3cc0f9a5464aba1284d651dd0e0b..a45e8d0e4b11d14cf5ad7af0a82404b2f6f01162 100644
--- a/src/Tools/tnl-mesh-convert.h
+++ b/src/Tools/tnl-mesh-convert.h
@@ -73,9 +73,9 @@ bool readNetgenMesh( const Config::ParameterContainer& parameters )
    if( ! meshReader.detectMesh( inputFileName ) )
       return false;
 
-  std::cout << "Reading mesh with " << meshReader.getDimensions() << " dimensions..." << std::endl;
+  std::cout << "Reading mesh with " << meshReader.getDimension() << " dimensions..." << std::endl;
  
-   if( meshReader.getDimensions() == 2 )
+   if( meshReader.getDimension() == 2 )
    {
       if( meshReader.getVerticesInCell() == 3 )
       {
@@ -90,7 +90,7 @@ bool readNetgenMesh( const Config::ParameterContainer& parameters )
          return convertMesh< MeshReaderNetgen, MeshType >( parameters );
       }
    }
-   if( meshReader.getDimensions() == 3 )
+   if( meshReader.getDimension() == 3 )
    {
       if( meshReader.getVerticesInCell() == 4 )
       {
@@ -105,7 +105,7 @@ bool readNetgenMesh( const Config::ParameterContainer& parameters )
          return convertMesh< MeshReaderNetgen, MeshType >( parameters );
       }
    }
-   std::cerr << "Wrong mesh dimensions were detected ( " << meshReader.getDimensions() << " )." << std::endl;
+   std::cerr << "Wrong mesh dimensions were detected ( " << meshReader.getDimension() << " )." << std::endl;
    return false;
 }
 
diff --git a/src/Tools/tnl-quickstart/Makefile.in b/src/Tools/tnl-quickstart/Makefile.in
index 48f3908b58d9888aa6cda6959ba65c96745793c7..c2954e00e8f855f14bd52eda44fc77f95c8a9416 100644
--- a/src/Tools/tnl-quickstart/Makefile.in
+++ b/src/Tools/tnl-quickstart/Makefile.in
@@ -1,6 +1,3 @@
-# Uncomment the following line to enable CUDA
-#WITH_CUDA = yes
-
 TARGET = {problemBaseName}
 INSTALL_DIR = ${{HOME}}/local
 
@@ -16,11 +13,12 @@ endif
 
 SOURCES = {problemBaseName}.cpp
 HEADERS = {problemBaseName}.h
-OBJECTS = {problemBaseName}.o
 DIST = $(SOURCES) $(CUDA_SOURCES) $(HEADERS) Makefile
 
 ifdef WITH_CUDA
    OBJECTS = {problemBaseName}-cuda.o
+else
+   OBJECTS = {problemBaseName}.o
 endif
      
 all: $(TARGET)
diff --git a/src/Tools/tnl-quickstart/build-config-tag.h.in b/src/Tools/tnl-quickstart/build-config-tag.h.in
index b965a6db1c0a8a4a01dafb2a4c77bf211e8bb298..c72d8c1b9dd30c104ff3530cef8c715c04a0e7ee 100644
--- a/src/Tools/tnl-quickstart/build-config-tag.h.in
+++ b/src/Tools/tnl-quickstart/build-config-tag.h.in
@@ -22,14 +22,14 @@ template<> struct ConfigTagIndex< {problemBaseName}BuildConfigTag, long int >{{
 /****
  * With how many dimensions may have the problem to be solved...
  */    
-template< int Dimensions > struct ConfigTagDimensions< {problemBaseName}BuildConfigTag, Dimensions >{{ enum {{ enabled = ( Dimensions == 1 ) }}; }};
+template< int Dimension > struct ConfigTagDimension< {problemBaseName}BuildConfigTag, Dimension >{{ enum {{ enabled = ( Dimension == 1 ) }}; }};
 
 /****
  * Use of Meshes::Grid is enabled for allowed dimensions and Real, Device and Index types.
  */
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< {problemBaseName}BuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      {{ enum {{ enabled = ConfigTagDimensions< {problemBaseName}BuildConfigTag, Dimensions >::enabled  &&
+template< int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< {problemBaseName}BuildConfigTag, Meshes::Grid< Dimension, Real, Device, Index > >
+      {{ enum {{ enabled = ConfigTagDimension< {problemBaseName}BuildConfigTag, Dimension >::enabled  &&
                          ConfigTagReal< {problemBaseName}BuildConfigTag, Real >::enabled &&
                          ConfigTagDevice< {problemBaseName}BuildConfigTag, Device >::enabled &&
                          ConfigTagIndex< {problemBaseName}BuildConfigTag, Index >::enabled }}; }};
diff --git a/src/Tools/tnl-quickstart/explicit-laplace-grid-1d_impl.h.in b/src/Tools/tnl-quickstart/explicit-laplace-grid-1d_impl.h.in
index d952cb637c3ca0afdedd577a7b6341d65c8e211e..1e1eaa44a175c7688f1b6864e9f7e5ffaea1fa5e 100644
--- a/src/Tools/tnl-quickstart/explicit-laplace-grid-1d_impl.h.in
+++ b/src/Tools/tnl-quickstart/explicit-laplace-grid-1d_impl.h.in
@@ -1,5 +1,5 @@
    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 >(); 
+   const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); 
    return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
\ No newline at end of file
diff --git a/src/Tools/tnl-quickstart/explicit-laplace-grid-2d_impl.h.in b/src/Tools/tnl-quickstart/explicit-laplace-grid-2d_impl.h.in
index ad817b3b31fc422759a76d4093336e67dee6a6dc..8c3b7d796ce12d8bb96fda55e47d55568bd8d5bd 100644
--- a/src/Tools/tnl-quickstart/explicit-laplace-grid-2d_impl.h.in
+++ b/src/Tools/tnl-quickstart/explicit-laplace-grid-2d_impl.h.in
@@ -1,9 +1,9 @@
    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 >();         
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();         
    return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
           ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse;
\ No newline at end of file
diff --git a/src/Tools/tnl-quickstart/explicit-laplace-grid-3d_impl.h.in b/src/Tools/tnl-quickstart/explicit-laplace-grid-3d_impl.h.in
index 7b2f234c2037ee8de516d2d04a0877e307e64e12..aa6ff5f3f7fcc731c57667cc3e12c52ca0087218 100644
--- a/src/Tools/tnl-quickstart/explicit-laplace-grid-3d_impl.h.in
+++ b/src/Tools/tnl-quickstart/explicit-laplace-grid-3d_impl.h.in
@@ -2,12 +2,12 @@
    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 >();         
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();         
+   const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+   const IndexType& down  = neighborEntities.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;
\ No newline at end of file
diff --git a/src/Tools/tnl-quickstart/implicit-laplace-grid-1d_impl.h.in b/src/Tools/tnl-quickstart/implicit-laplace-grid-1d_impl.h.in
index de086c72e305d76b2130e0a2e09da73f68c40fd1..e5a139e22c202672510f59b607c5d099d2772c4e 100644
--- a/src/Tools/tnl-quickstart/implicit-laplace-grid-1d_impl.h.in
+++ b/src/Tools/tnl-quickstart/implicit-laplace-grid-1d_impl.h.in
@@ -1,7 +1,7 @@
    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 >(); 
+   const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); 
    matrixRow.setElement( 0, west,   - lambdaX );
    matrixRow.setElement( 1, center, 2.0 * lambdaX );
    matrixRow.setElement( 2, east,   - lambdaX );
\ No newline at end of file
diff --git a/src/Tools/tnl-quickstart/implicit-laplace-grid-2d_impl.h.in b/src/Tools/tnl-quickstart/implicit-laplace-grid-2d_impl.h.in
index 048949469ddff7d49bbd7ca82e74ff322fa789cd..808d829a88028d9e75c6a6bbaa1b092d3ce4d361 100644
--- a/src/Tools/tnl-quickstart/implicit-laplace-grid-2d_impl.h.in
+++ b/src/Tools/tnl-quickstart/implicit-laplace-grid-2d_impl.h.in
@@ -1,10 +1,10 @@
    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 >();         
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >();         
    matrixRow.setElement( 0, south,  -lambdaY );
    matrixRow.setElement( 1, west,   -lambdaX );
    matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
diff --git a/src/Tools/tnl-quickstart/implicit-laplace-grid-3d_impl.h.in b/src/Tools/tnl-quickstart/implicit-laplace-grid-3d_impl.h.in
index 2343334c4044143815dc5ebfad19fc2c26e767c3..7bbec43866834f69db96e250aaaec9af8c717586 100644
--- a/src/Tools/tnl-quickstart/implicit-laplace-grid-3d_impl.h.in
+++ b/src/Tools/tnl-quickstart/implicit-laplace-grid-3d_impl.h.in
@@ -2,12 +2,12 @@
    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 >();                 
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >();         
+   const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+   const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >();                 
    matrixRow.setElement( 0, down,   -lambdaZ );
    matrixRow.setElement( 1, south,  -lambdaY );
    matrixRow.setElement( 2, west,   -lambdaX );
diff --git a/src/Tools/tnl-quickstart/main.h.in b/src/Tools/tnl-quickstart/main.h.in
index 4fd410563132bbc17a77a0d359aad58961fda339..f836967c83ccc88fed8898a0c344a9ea08e40906 100644
--- a/src/Tools/tnl-quickstart/main.h.in
+++ b/src/Tools/tnl-quickstart/main.h.in
@@ -58,10 +58,10 @@ class {problemBaseName}Setter
 
       static bool run( const Config::ParameterContainer & parameters )
       {{
-          enum {{ Dimensions = MeshType::getMeshDimensions() }};
+          enum {{ Dimension = MeshType::getMeshDimension() }};
           typedef {operatorName}< MeshType, Real, Index > ApproximateOperator;
           typedef {problemBaseName}Rhs< MeshType, Real > RightHandSide;    
-          typedef Containers::StaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+          typedef Containers::StaticVector < MeshType::getMeshDimension(), Real > Vertex;
 
          /****
           * Resolve the template arguments of your solver here.
@@ -71,10 +71,10 @@ class {problemBaseName}Setter
           String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
           if( parameters.checkParameter( "boundary-conditions-constant" ) )
           {{
-             typedef Functions::Analytic::Constant< Dimensions, Real > ConstantFunction;
+             typedef Functions::Analytic::Constant< Dimension, Real > ConstantFunction;
              if( boundaryConditionsType == "dirichlet" )
              {{
-                typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunction, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
                 typedef {problemBaseName}Problem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
                 SolverStarter solverStarter;
                 return solverStarter.template run< Problem >( parameters );
@@ -86,8 +86,8 @@ class {problemBaseName}Setter
           }}
           typedef Functions::MeshFunction< MeshType > MeshFunction;
           if( boundaryConditionsType == "dirichlet" )
-          {{
-             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+          {{    
+             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
              typedef {problemBaseName}Problem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
              SolverStarter solverStarter;
              return solverStarter.template run< Problem >( parameters );
diff --git a/src/Tools/tnl-quickstart/operator-grid-specialization.h.in b/src/Tools/tnl-quickstart/operator-grid-specialization.h.in
index de06efc27e04caa98c02521abd936c88c7a7c259..e67c5e007a02f45bce36eb079ae529c27f7dce0f 100644
--- a/src/Tools/tnl-quickstart/operator-grid-specialization.h.in
+++ b/src/Tools/tnl-quickstart/operator-grid-specialization.h.in
@@ -3,16 +3,16 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-class {operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex >, Real, Index >
+class {operatorName}< TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex >, Real, Index >
 {{
    public:
-      typedef TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex > MeshType;
+      typedef TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex > MeshType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef TNL::Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum {{ Dimensions = MeshType::getMeshDimensions() }};
+      enum {{ Dimension = MeshType::getMeshDimension() }};
 
       static TNL::String getType();
 
@@ -22,8 +22,8 @@ class {operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, Mes
                        const MeshEntity& entity,
                        const RealType& time = 0.0 ) const;
 
-      __cuda_callable__
       template< typename MeshEntity >    
+      __cuda_callable__
       Index getLinearSystemRowLength( const MeshType& mesh,
                                       const IndexType& index,
                                       const MeshEntity& entity ) const;
diff --git a/src/Tools/tnl-quickstart/operator-grid-specialization_impl.h.in b/src/Tools/tnl-quickstart/operator-grid-specialization_impl.h.in
index cf73e55f5805a133a269b6a856ecf5be04804af1..3e7d0d670f5de48659c146bbf7b1fb62287e4a38 100644
--- a/src/Tools/tnl-quickstart/operator-grid-specialization_impl.h.in
+++ b/src/Tools/tnl-quickstart/operator-grid-specialization_impl.h.in
@@ -1,5 +1,5 @@
 /****
- * {meshDimensions}D problem
+ * {meshDimension}D problem
  */
 template< typename MeshReal,
           typename Device,
@@ -7,7 +7,7 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 TNL::String
-{operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex >, Real, Index >::
+{operatorName}< TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex >, Real, Index >::
 getType()
 {{
    return TNL::String( "{operatorName}< " ) +
@@ -24,7 +24,7 @@ template< typename MeshReal,
 template< typename MeshFunction, typename MeshEntity >
 __cuda_callable__
 Real
-{operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex >, Real, Index >::
+{operatorName}< TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex >, Real, Index >::
 operator()( const MeshFunction& u,
             const MeshEntity& entity,
             const Real& time ) const
@@ -34,9 +34,9 @@ operator()( const MeshFunction& u,
     * The following example is the Laplace operator approximated 
     * by the Finite difference method.
     */  
-   static_assert( MeshEntity::entityDimensions == {meshDimensions}, "Wrong mesh entity dimensions." );
-   static_assert( MeshFunction::getEntitiesDimensions() == {meshDimensions}, "Wrong preimage function" );
-   const typename MeshEntity::template NeighbourEntities< {meshDimensions} >& neighbourEntities = entity.getNeighbourEntities(); 
+   static_assert( MeshEntity::entityDimension == {meshDimension}, "Wrong mesh entity dimensions." );
+   static_assert( MeshFunction::getEntitiesDimension() == {meshDimension}, "Wrong preimage function" );
+   const typename MeshEntity::template NeighborEntities< {meshDimension} >& neighborEntities = entity.getNeighborEntities(); 
 
 {explicitScheme}
 }}
@@ -49,7 +49,7 @@ template< typename MeshReal,
 template< typename MeshEntity >
 __cuda_callable__
 Index
-{operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex >, Real, Index >::
+{operatorName}< TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex >, Real, Index >::
 getLinearSystemRowLength( const MeshType& mesh,
                           const IndexType& index,
                           const MeshEntity& entity ) const
@@ -61,7 +61,7 @@ getLinearSystemRowLength( const MeshType& mesh,
     * by the Finite difference method.
     */
 
-   return 2*Dimensions + 1;
+   return 2*Dimension + 1;
 }}
 
 template< typename MeshReal,
@@ -76,7 +76,7 @@ template< typename MeshReal,
 __cuda_callable__
 inline
 void
-{operatorName}< TNL::Meshes::Grid< {meshDimensions}, MeshReal, Device, MeshIndex >, Real, Index >::
+{operatorName}< TNL::Meshes::Grid< {meshDimension}, MeshReal, Device, MeshIndex >, Real, Index >::
 setMatrixElements( const PreimageFunction& u,
                    const MeshEntity& entity,
                    const RealType& time,
@@ -84,15 +84,15 @@ setMatrixElements( const PreimageFunction& u,
                    Matrix& matrix,
                    Vector& b ) const
 {{
-   static_assert( MeshEntity::entityDimensions == {meshDimensions}, "Wrong mesh entity dimensions." );
-   static_assert( PreimageFunction::getEntitiesDimensions() == {meshDimensions}, "Wrong preimage function" );
+   static_assert( MeshEntity::entityDimension == {meshDimension}, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimension() == {meshDimension}, "Wrong preimage function" );
 
    /****
     * Setup the non-zero elements of the linear system here.
     * The following example is the Laplace operator approximated 
     * by the Finite difference method.
     */    
-   const typename MeshEntity::template NeighbourEntities< {meshDimensions} >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::template NeighborEntities< {meshDimension} >& neighborEntities = entity.getNeighborEntities();
    const IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
 {semiimplicitScheme}
diff --git a/src/Tools/tnl-quickstart/problem.h.in b/src/Tools/tnl-quickstart/problem.h.in
index def92930e372d2a7ad22349f85d9e88f2e47584b..dd53ffe43f77e58a5dd49cdc51306820a0b07249 100644
--- a/src/Tools/tnl-quickstart/problem.h.in
+++ b/src/Tools/tnl-quickstart/problem.h.in
@@ -2,6 +2,10 @@
 
 #include <TNL/Problems/PDEProblem.h>
 #include <TNL/Functions/MeshFunction.h>
+#include <TNL/Solvers/PDE/ExplicitUpdater.h>
+#include <TNL/Solvers/PDE/LinearSystemAssembler.h>
+#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h>
+
 
 template< typename Mesh,
           typename BoundaryCondition,
@@ -29,6 +33,7 @@ class {problemBaseName}Problem:
       using typename BaseType::DofVectorType;
       using typename BaseType::DofVectorPointer;
       using typename BaseType::MeshDependentDataType;
+      using typename BaseType::MeshDependentDataPointer;
 
 
       static TNL::String getTypeStatic();
@@ -46,7 +51,7 @@ class {problemBaseName}Problem:
       bool setInitialCondition( const TNL::Config::ParameterContainer& parameters,
                                 const MeshPointer& mesh,
                                 DofVectorPointer& dofs,
-                                MeshDependentDataType& meshDependentData );
+                                MeshDependentDataPointer& meshDependentData );
 
       template< typename MatrixPointer >
       bool setupLinearSystem( const MeshPointer& mesh,
@@ -56,19 +61,19 @@ class {problemBaseName}Problem:
                          const IndexType& step,
                          const MeshPointer& mesh,
                          DofVectorPointer& dofs,
-                         MeshDependentDataType& meshDependentData );
+                         MeshDependentDataPointer& meshDependentData );
 
       IndexType getDofs( const MeshPointer& mesh ) const;
 
       void bindDofs( const MeshPointer& mesh,
                      DofVectorPointer& dofs );
 
-      void getExplicitRHS( const RealType& time,
-                           const RealType& tau,
-                           const MeshPointer& mesh,
-                           DofVectorPointer& _u,
-                           DofVectorPointer& _fu,
-                           MeshDependentDataType& meshDependentData );
+      void getExplicitUpdate( const RealType& time,
+                              const RealType& tau,
+                              const MeshPointer& mesh,
+                              DofVectorPointer& _u,
+                              DofVectorPointer& _fu,
+                              MeshDependentDataPointer& meshDependentData );
 
       template< typename MatrixPointer >
       void assemblyLinearSystem( const RealType& time,
@@ -77,13 +82,23 @@ class {problemBaseName}Problem:
                                  DofVectorPointer& dofs,
                                  MatrixPointer& matrixPointer,
                                  DofVectorPointer& rightHandSide,
-                                 MeshDependentDataType& meshDependentData );
+                                 MeshDependentDataPointer& meshDependentData );
 
    protected:
     
       DifferentialOperatorPointer differentialOperator;
       BoundaryConditionPointer boundaryCondition;
       RightHandSidePointer rightHandSide;
+   
+      TNL::Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+
+      TNL::Solvers::PDE::LinearSystemAssembler< Mesh, 
+                                                MeshFunctionType,
+                                                DifferentialOperator,
+                                                BoundaryCondition,
+                                                RightHandSide,
+                                                TNL::Solvers::PDE::BackwardTimeDiscretisation,
+                                                DofVectorType > systemAssembler;
 }};
 
 #include "{problemBaseName}Problem_impl.h"
diff --git a/src/Tools/tnl-quickstart/problem_impl.h.in b/src/Tools/tnl-quickstart/problem_impl.h.in
index 0a495676127f6e5a5f85402ebc7c994d19c79c36..d0b1162383eea26cf35282ecb78b9b5143f4abdb 100644
--- a/src/Tools/tnl-quickstart/problem_impl.h.in
+++ b/src/Tools/tnl-quickstart/problem_impl.h.in
@@ -94,7 +94,7 @@ bool
 setInitialCondition( const TNL::Config::ParameterContainer& parameters,    
                      const MeshPointer& mesh,
                      DofVectorPointer& dofs,
-                     MeshDependentDataType& meshDependentData )
+                     MeshDependentDataPointer& meshDependentData )
 {{
    const TNL::String& initialConditionFile = parameters.getParameter< TNL::String >( "initial-condition" );
    TNL::Functions::MeshFunction< Mesh > u( mesh, dofs );
@@ -117,17 +117,17 @@ setupLinearSystem( const MeshPointer& meshPointer,
                    MatrixPointer& matrixPointer )
 {{
    const IndexType dofs = this->getDofs( meshPointer );
-   typedef typename MatrixPointer::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   TNL::SharedPointer< CompressedRowsLengthsVectorType > rowLengthsPointer;
+   typedef typename MatrixPointer::ObjectType::CompressedRowLengthsVector CompressedRowLengthsVectorType;
+   TNL::SharedPointer< CompressedRowLengthsVectorType > rowLengthsPointer;
    if( ! rowLengthsPointer->setSize( dofs ) )
       return false;
-   TNL::Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( meshPointer,
-                                                                          differentialOperator,
-                                                                          boundaryCondition,
-                                                                          rowLengthsPointer );
+   TNL::Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >( meshPointer,
+                                                                         differentialOperator,
+                                                                         boundaryCondition,
+                                                                         rowLengthsPointer );
    matrixPointer->setDimensions( dofs, dofs );
-   if( ! matrixPointer->setCompressedRowsLengths( *rowLengthsPointer ) )
+   if( ! matrixPointer->setCompressedRowLengths( *rowLengthsPointer ) )
       return false;
    return true;
 }}
@@ -142,7 +142,7 @@ makeSnapshot( const RealType& time,
               const IndexType& step,
               const MeshPointer& mesh,
               DofVectorPointer& dofs,
-              MeshDependentDataType& meshDependentData )
+              MeshDependentDataPointer& meshDependentData )
 {{
    std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
    this->bindDofs( mesh, dofs );
@@ -161,15 +161,15 @@ template< typename Mesh,
           typename DifferentialOperator >
 void
 {problemBaseName}Problem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::                    
-getExplicitRHS( const RealType& time,
-                const RealType& tau,
-                const MeshPointer& mesh,
-                DofVectorPointer& _u,
-                DofVectorPointer& _fu,
-                MeshDependentDataType& meshDependentData )
+getExplicitUpdate( const RealType& time,
+                   const RealType& tau,
+                   const MeshPointer& mesh,
+                   DofVectorPointer& _u,
+                   DofVectorPointer& _fu,
+                   MeshDependentDataPointer& meshDependentData )
 {{
    /****
-    * If you use an explicit solver like tnlEulerSolver or tnlMersonSolver, you
+    * If you use an explicit solver like EulerSolver or MersonSolver, you
     * need to implement this method. Compute the right-hand side of
     *
     *   d/dt u(x) = fu( x, u )
@@ -177,22 +177,12 @@ getExplicitRHS( const RealType& time,
     * You may use supporting mesh dependent data if you need.
     */
 
-   this->bindDofs( mesh, _u );
-   TNL::Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
-   TNL::SharedPointer< MeshFunctionType > u( mesh, _u ); 
-   TNL::SharedPointer< MeshFunctionType > fu( mesh, _fu ); 
-   explicitUpdater.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           this->differentialOperator,
-                                                           this->boundaryCondition,
-                                                           this->rightHandSide,
-                                                           u,
-                                                           fu );
-   TNL::Solvers::PDE::BoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; 
-   boundaryConditionsSetter.template apply< typename Mesh::Cell >( 
-      this->boundaryCondition, 
-      time + tau,
-      u );
+   TNL::SharedPointer< MeshFunctionType > uPointer( mesh, _u ); 
+   TNL::SharedPointer< MeshFunctionType > fuPointer( mesh, _fu ); 
+   this->explicitUpdater.setDifferentialOperator( this->differentialOperator ),
+   this->explicitUpdater.setBoundaryConditions( this->boundaryCondition ),
+   this->explicitUpdater.setRightHandSide( this->rightHandSide ),
+   this->explicitUpdater.template update< typename Mesh::Cell >( time, tau, mesh, uPointer, fuPointer );
 }}
 
 template< typename Mesh,
@@ -208,25 +198,23 @@ assemblyLinearSystem( const RealType& time,
                       DofVectorPointer& _u,
                       MatrixPointer& matrixPointer,
                       DofVectorPointer& b,
-                      MeshDependentDataType& meshDependentData )
+                      MeshDependentDataPointer& meshDependentData )
 {{
-   TNL::Solvers::PDE::LinearSystemAssembler< Mesh,
-                             MeshFunctionType,
-                             DifferentialOperator,
-                             BoundaryCondition,
-                             RightHandSide,
-                             TNL::Solvers::PDE::BackwardTimeDiscretisation,
-                             typename MatrixPointer::ObjectType,
-                             DofVectorType > systemAssembler;
+   /****
+    * If you implement a (semi-)implicit solver, this method is supposed
+    * to assembly the global linear system in each time step.
+    * You may use supporting mesh dependent data if you need.
+    */
 
-   TNL::SharedPointer< TNL::Functions::MeshFunction< Mesh > > u( mesh, _u );
-   systemAssembler.template assembly< typename Mesh::Cell >( time,
-                                                             tau,
-                                                             mesh,
-                                                             this->differentialOperator,
-                                                             this->boundaryCondition,
-                                                             this->rightHandSide,
-                                                             u,
-                                                             matrixPointer,
-                                                             b );
+   TNL::SharedPointer< TNL::Functions::MeshFunction< Mesh > > uPointer( mesh, _u );
+   this->systemAssembler.setDifferentialOperator( this->differentialOperator );
+   this->systemAssembler.setBoundaryConditions( this->boundaryCondition );
+   this->systemAssembler.setRightHandSide( this->rightHandSide );
+   this->systemAssembler.template assembly< typename Mesh::Cell, typename MatrixPointer::ObjectType >( 
+      time,
+      tau,
+      mesh,
+      uPointer,
+      matrixPointer,
+      b );
 }}
diff --git a/src/Tools/tnl-quickstart/rhs.h.in b/src/Tools/tnl-quickstart/rhs.h.in
index 71f3d1e79eebc705c73e9e0b522a5ae93e0a0ce5..ffd1b78813dbfcd2f17809fcea69f2d999e86b89 100644
--- a/src/Tools/tnl-quickstart/rhs.h.in
+++ b/src/Tools/tnl-quickstart/rhs.h.in
@@ -4,7 +4,7 @@
 
 template< typename Mesh, typename Real >
 class {problemBaseName}Rhs
-  : public TNL::Functions::Domain< Mesh::meshDimensions, TNL::Functions::MeshDomain >
+  : public TNL::Functions::Domain< Mesh::meshDimension, TNL::Functions::MeshDomain >
 {{
    public:
 
@@ -22,8 +22,8 @@ class {problemBaseName}Rhs
       Real operator()( const MeshEntity& entity,
                        const Real& time = 0.0 ) const    
       {{   
-         typedef typename MeshEntity::MeshType::VertexType VertexType;
-         VertexType v = entity.getCenter();        
+         typedef typename MeshEntity::MeshType::PointType PointType;
+         PointType p = entity.getCenter();        
          return 0.0;    
       }}
 }};
\ No newline at end of file
diff --git a/src/Tools/tnl-quickstart/tnl-quickstart.py b/src/Tools/tnl-quickstart/tnl-quickstart.py
index 4242a2c085fae5d83cc5747632035439d7fbd5d7..f456952696ad52d06fb7e3806e885dbc62d33be1 100644
--- a/src/Tools/tnl-quickstart/tnl-quickstart.py
+++ b/src/Tools/tnl-quickstart/tnl-quickstart.py
@@ -18,7 +18,7 @@ print( "----------------------------------")
 
 definitions = {}
 
-definitions['problemName'] = input( "Problam name:" )
+definitions['problemName'] = input( "Problem name:" )
 definitions['problemBaseName'] = input( "Problem class base name (base name acceptable in C++ code):" )
 definitions['operatorName'] = input( "Operator name:")
 
@@ -40,7 +40,7 @@ with open( definitions['problemBaseName']+".h", 'w') as file:
 
 with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/main.cu.in", 'r') as ftemp:
     templateString = ftemp.read()
-with open( definitions['problemBaseName']+".cu", 'w') as file:
+with open( definitions['problemBaseName']+"-cuda.cu", 'w') as file:
     file.write( templateString.format(**definitions ) )
 
 with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/main.cpp.in", 'r') as ftemp:
@@ -65,19 +65,19 @@ with open( definitions['problemBaseName'] + "Problem_impl.h", 'w') as file:
 # Operator
 #
 dimensions = [ '1', '2', '3' ]
-for meshDimensions in dimensions:
-   definitions[ 'meshDimensions' ] = meshDimensions
-   key = 'operatorGridSpecializationHeader_' + meshDimensions + 'D'
+for meshDimension in dimensions:
+   definitions[ 'meshDimension' ] = meshDimension
+   key = 'operatorGridSpecializationHeader_' + meshDimension + 'D'
    with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/operator-grid-specialization.h.in", 'r') as ftemp:
        templateString = ftemp.read()
    definitions[ key ] = templateString.format( **definitions )
 
-   with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/explicit-laplace-grid-" + meshDimensions + "d_impl.h.in", 'r') as ftemp:
+   with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/explicit-laplace-grid-" + meshDimension + "d_impl.h.in", 'r') as ftemp:
       definitions[ 'explicitScheme' ] = ftemp.read();
-   with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/implicit-laplace-grid-" + meshDimensions + "d_impl.h.in", 'r') as ftemp:
+   with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/implicit-laplace-grid-" + meshDimension + "d_impl.h.in", 'r') as ftemp:
       definitions[ 'semiimplicitScheme' ] = ftemp.read();
 
-   key = 'operatorGridSpecializationImplementation_' + meshDimensions + 'D'
+   key = 'operatorGridSpecializationImplementation_' + meshDimension + 'D'
    with open( TNL.Config.tnl_install_prefix+"/share/tnl-" + TNL.Config.tnl_version + "/operator-grid-specialization_impl.h.in", 'r') as ftemp:
        templateString = ftemp.read()
    definitions[ key ] = templateString.format( **definitions )
diff --git a/src/Tools/tnl-view.cpp b/src/Tools/tnl-view.cpp
index f7d974821f6d702b6a23afa6bfe33e82d8d1703a..4a5865ac610e5d0713899f9a72678ab878f13d76 100644
--- a/src/Tools/tnl-view.cpp
+++ b/src/Tools/tnl-view.cpp
@@ -71,11 +71,11 @@ int main( int argc, char* argv[] )
       return EXIT_FAILURE;
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
-   List< String > parsedMeshType;
+   Containers::List< String > parsedMeshType;
    if( ! parseObjectType( meshType, parsedMeshType ) )
    {
       std::cerr << "Unable to parse the mesh type " << meshType << "." << std::endl;
-      return false;
+      return EXIT_FAILURE;
    }
    if( parsedMeshType[ 0 ] == "Meshes::Grid" ||
        parsedMeshType[ 0 ] == "tnlGrid" )   //  TODO: remove deprecated type name
diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h
index c396954ae697ed28d15a8849309e16f7bb48c2c6..c4d25f1d5520d2886be390bc41763c1f338e45aa 100644
--- a/src/Tools/tnl-view.h
+++ b/src/Tools/tnl-view.h
@@ -19,8 +19,8 @@
 #include <TNL/Containers/MultiVector.h>
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Functions/MeshFunction.h>
+#include <TNL/Functions/VectorField.h>
 
-using namespace std;
 using namespace TNL;
 
 bool getOutputFileName( const String& inputFileName,
@@ -49,7 +49,9 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer,
                         const String& inputFileName,
                         const Config::ParameterContainer& parameters  )
 {
+
    MeshFunction function( meshPointer );
+   std::cout << "Mesh function: " << function.getType() << std::endl;
    if( ! function.load( inputFileName ) )
    {
       std::cerr << "Unable to load mesh function from a file " << inputFileName << "." << std::endl;
@@ -58,6 +60,7 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer,
 
    int verbose = parameters. getParameter< int >( "verbose");
    String outputFormat = parameters. getParameter< String >( "output-format" );
+   double scale = parameters. getParameter< double >( "scale" );
    String outputFileName;
    if( ! getOutputFileName( inputFileName,
                             outputFormat,
@@ -66,136 +69,201 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer,
    if( verbose )
      std::cout << " writing to " << outputFileName << " ... " << std::flush;
 
-   return function.write( outputFileName, outputFormat );
+   return function.write( outputFileName, outputFormat, scale );
 }
 
+template< typename VectorField >
+bool writeVectorField( const typename VectorField::FunctionType::MeshPointer& meshPointer,
+                       const String& inputFileName,
+                       const Config::ParameterContainer& parameters  )
+{
+
+   VectorField field( meshPointer );
+   std::cout << "VectorField: " << field.getType() << std::endl;
+   if( ! field.load( inputFileName ) )
+   {
+      std::cerr << "Unable to load vector field from a file " << inputFileName << "." << std::endl;
+      return false;
+   }
+
+   int verbose = parameters. getParameter< int >( "verbose");
+   String outputFormat = parameters. getParameter< String >( "output-format" );
+   double scale = parameters. getParameter< double >( "scale" );
+   String outputFileName;
+   if( ! getOutputFileName( inputFileName,
+                            outputFormat,
+                            outputFileName ) )
+      return false;
+   if( verbose )
+     std::cout << " writing to " << outputFileName << " ... " << std::flush;
+
+   return field.write( outputFileName, outputFormat, scale );
+}
+
+
 template< typename MeshPointer,
-          int EntityDimensions,
-          typename Real >
+          int EntityDimension,
+          typename Real,
+          int VectorFieldSize >
 bool setMeshFunctionRealType( const MeshPointer& meshPointer,
                               const String& inputFileName,
+                              const Containers::List< String >& parsedObjectType,
                               const Config::ParameterContainer& parameters  )
 {
-   return writeMeshFunction< Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimensions, Real > >( meshPointer, inputFileName, parameters );
+   if( VectorFieldSize == 0 )
+      return writeMeshFunction< Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimension, Real > >( meshPointer, inputFileName, parameters );
+   return writeVectorField< Functions::VectorField< VectorFieldSize, Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimension, Real > > >( meshPointer, inputFileName, parameters );
 }
 
 template< typename MeshPointer,
-          int EntityDimensions >
+          int EntityDimension,
+          int VectorFieldSize >
 bool setMeshEntityType( const MeshPointer& meshPointer,
                         const String& inputFileName,
-                        const List< String >& parsedObjectType,
+                        const Containers::List< String >& parsedObjectType,
                         const Config::ParameterContainer& parameters )
 {
    if( parsedObjectType[ 3 ] == "float" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, float >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimension, float, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( parsedObjectType[ 3 ] == "double" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, double >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimension, double, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( parsedObjectType[ 3 ] == "long double" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, long double >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimension, long double, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
    std::cerr << "Unsupported arithmetics " << parsedObjectType[ 3 ] << " in mesh function " << inputFileName << std::endl;
    return false;
 }
 
 template< typename MeshReal,
-          typename MeshIndex >
-bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
+          typename MeshIndex,
+          int VectorFieldSize >
+bool setMeshEntityDimension( const SharedPointer< Meshes::Grid< 1, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
-                              const List< String >& parsedObjectType,
+                              const Containers::List< String >& parsedObjectType,
                               const Config::ParameterContainer& parameters )
 {
    typedef Meshes::Grid< 1, MeshReal, Devices::Host, MeshIndex > Mesh;
    typedef SharedPointer< Mesh > MeshPointer;
-   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
-   switch( meshEntityDimensions )
+   int meshEntityDimension = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimension )
    {
       case 0:
-         return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;      
       case 1:
-         return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       default:
-         std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl;
+         std::cerr << "Unsupported mesh functions entity dimension count " << meshEntityDimension << "." << std::endl;
          return false;
    }
 }
 
 template< typename MeshReal,
-          typename MeshIndex >
-bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
+          typename MeshIndex,
+          int VectorFieldSize >
+bool setMeshEntityDimension( const SharedPointer< Meshes::Grid< 2, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
-                              const List< String >& parsedObjectType,
+                              const Containers::List< String >& parsedObjectType,
                               const Config::ParameterContainer& parameters )
 {
    typedef Meshes::Grid< 2, MeshReal, Devices::Host, MeshIndex > Mesh;
    typedef SharedPointer< Mesh > MeshPointer;
-   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
-   switch( meshEntityDimensions )
+   int meshEntityDimension = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimension )
    {
       case 0:
-         return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;            
       case 1:
-         return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       case 2:
-         return setMeshEntityType< MeshPointer, 2 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 2, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       default:
-         std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl;
+         std::cerr << "Unsupported mesh functions entity dimension count " << meshEntityDimension << "." << std::endl;
          return false;
    }
 }
 
 template< typename MeshReal,
-          typename MeshIndex >
-bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
+          typename MeshIndex,
+          int VectorFieldSize >
+bool setMeshEntityDimension( const SharedPointer< Meshes::Grid< 3, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
-                              const List< String >& parsedObjectType,
+                              const Containers::List< String >& parsedObjectType,
                               const Config::ParameterContainer& parameters )
 {
    typedef Meshes::Grid< 3, MeshReal, Devices::Host, MeshIndex > Mesh;
    typedef SharedPointer< Mesh > MeshPointer;
-   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
-   switch( meshEntityDimensions )
+   int meshEntityDimension = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimension )
    {
       case 0:
-         return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;      
       case 1:
-         return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       case 2:
-         return setMeshEntityType< MeshPointer, 2 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 2, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       case 3:
-         return setMeshEntityType< MeshPointer, 3 >( meshPointer, inputFileName, parsedObjectType, parameters );
+         return setMeshEntityType< MeshPointer, 3, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
          break;
       default:
-         std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl;
+         std::cerr << "Unsupported mesh functions entity dimension count " << meshEntityDimension << "." << std::endl;
          return false;
    }
 }
 
-template< typename MeshPointer >
+template< typename MeshPointer, int VectorFieldSize = 0 >
 bool setMeshFunction( const MeshPointer& meshPointer,
                       const String& inputFileName,
-                      const List< String >& parsedObjectType,
+                      const Containers::List< String >& parsedObjectType,
                       const Config::ParameterContainer& parameters )
 {
+   std::cerr << parsedObjectType[ 1 ] << std::endl;
    if( parsedObjectType[ 1 ] != meshPointer->getSerializationType() )
    {
       std::cerr << "Incompatible mesh type for the mesh function " << inputFileName << "." << std::endl;
       return false;
    }
-   return setMeshEntityDimensions( meshPointer, inputFileName, parsedObjectType, parameters );
+   typedef typename MeshPointer::ObjectType::RealType RealType;
+   typedef typename MeshPointer::ObjectType::IndexType IndexType;
+   return setMeshEntityDimension< RealType, IndexType, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
 }
 
+template< typename MeshPointer >
+bool setVectorFieldSize( const MeshPointer& meshPointer,
+                         const String& inputFileName,
+                         Containers::List< String >& parsedObjectType,
+                         const Config::ParameterContainer& parameters )
+{
+   int vectorFieldSize = atoi( parsedObjectType[ 1 ].getString() );
+   Containers::List< String > parsedMeshFunctionType;
+   if( ! parseObjectType( parsedObjectType[ 2 ], parsedMeshFunctionType ) )
+   {
+      std::cerr << "Unable to parse mesh function type  " << parsedObjectType[ 2 ] << " in a vector field." << std::endl;
+      return false;
+   }
+   switch( vectorFieldSize )
+   {
+      case 1:
+         return setMeshFunction< MeshPointer, 1 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters );
+      case 2:
+         return setMeshFunction< MeshPointer, 2 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters );
+      case 3:
+         return setMeshFunction< MeshPointer, 3 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters );
+   }
+   std::cerr << "Unsupported vector field size " << vectorFieldSize << "." << std::endl;
+   return false;
+}
 
-template< typename MeshPointer, typename Element, typename Real, typename Index, int Dimensions >
+template< typename MeshPointer, typename Element, typename Real, typename Index, int Dimension >
 bool convertObject( const MeshPointer& meshPointer,
                     const String& inputFileName,
-                    const List< String >& parsedObjectType,
+                    const Containers::List< String >& parsedObjectType,
                     const Config::ParameterContainer& parameters )
 {
    int verbose = parameters. getParameter< int >( "verbose");
@@ -213,10 +281,15 @@ bool convertObject( const MeshPointer& meshPointer,
        parsedObjectType[ 0 ] == "tnlSharedVector" ||   // TODO: remove deprecated type names
        parsedObjectType[ 0 ] == "tnlVector" )          //
    {
-      Containers::Vector< Element, Devices::Host, Index > vector;
-      if( ! vector. load( inputFileName ) )
+      using MeshType = typename MeshPointer::ObjectType;
+      // FIXME: why is MeshType::GlobalIndexType not the same as Index?
+//      Containers::Vector< Element, Devices::Host, Index > vector;
+      Containers::Vector< Element, Devices::Host, typename MeshType::GlobalIndexType > vector;
+      if( ! vector.load( inputFileName ) )
          return false;
-      if( ! meshPointer->write( vector, outputFileName, outputFormat ) )
+      Functions::MeshFunction< MeshType, MeshType::getMeshDimension(), Element > mf;
+      mf.bind( meshPointer, vector );
+      if( ! mf.write( outputFileName, outputFormat ) )
          return false;
    }
 
@@ -224,14 +297,14 @@ bool convertObject( const MeshPointer& meshPointer,
        parsedObjectType[ 0 ] == "tnlMultiVector" ||      // TODO: remove deprecated type names  
        parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) //
    {
-      Containers::MultiVector< Dimensions, Element, Devices::Host, Index > multiVector;
+      Containers::MultiVector< Dimension, Element, Devices::Host, Index > multiVector;
       if( ! multiVector. load( inputFileName ) )
          return false;
-      typedef Meshes::Grid< Dimensions, Real, Devices::Host, Index > GridType;
-      typedef typename GridType::VertexType VertexType;
+      typedef Meshes::Grid< Dimension, Real, Devices::Host, Index > GridType;
+      typedef typename GridType::PointType PointType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       GridType grid;
-      grid. setDomain( VertexType( 0.0 ), VertexType( 1.0 ) );
+      grid. setDomain( PointType( 0.0 ), PointType( 1.0 ) );
       grid. setDimensions( CoordinatesType( multiVector. getDimensions() ) );
       const Real spaceStep = grid. getSpaceSteps(). x();
       if( ! grid. write( multiVector, outputFileName, outputFormat ) )
@@ -243,7 +316,7 @@ bool convertObject( const MeshPointer& meshPointer,
 template< typename MeshPointer, typename Element, typename Real, typename Index >
 bool setDimensions( const MeshPointer& meshPointer,
                     const String& inputFileName,
-                    const List< String >& parsedObjectType,
+                    const Containers::List< String >& parsedObjectType,
                     const Config::ParameterContainer& parameters )
 {
    int dimensions( 0 );
@@ -271,7 +344,7 @@ bool setDimensions( const MeshPointer& meshPointer,
 template< typename MeshPointer, typename Element, typename Real >
 bool setIndexType( const MeshPointer& meshPointer,
                    const String& inputFileName,
-                   const List< String >& parsedObjectType,
+                   const Containers::List< String >& parsedObjectType,
                    const Config::ParameterContainer& parameters )
 {
    String indexType;
@@ -288,15 +361,15 @@ bool setIndexType( const MeshPointer& meshPointer,
       return setDimensions< MeshPointer, Element, Real, int >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( indexType == "long-int" )
       return setDimensions< MeshPointer, Element, Real, long int >( meshPointer, inputFileName, parsedObjectType, parameters );
-   cerr << "Unknown index type " << indexType << "." << endl;
+   std::cerr << "Unknown index type " << indexType << "." << std::endl;
    return false;
 }
 
 template< typename MeshPointer >
 bool setTupleType( const MeshPointer& meshPointer,
                    const String& inputFileName,
-                   const List< String >& parsedObjectType,
-                   const List< String >& parsedElementType,
+                   const Containers::List< String >& parsedObjectType,
+                   const Containers::List< String >& parsedElementType,
                    const Config::ParameterContainer& parameters )
 {
    int dimensions = atoi( parsedElementType[ 1 ].getString() );
@@ -346,7 +419,7 @@ bool setTupleType( const MeshPointer& meshPointer,
 template< typename MeshPointer >
 bool setElementType( const MeshPointer& meshPointer,
                      const String& inputFileName,
-                     const List< String >& parsedObjectType,
+                     const Containers::List< String >& parsedObjectType,
                      const Config::ParameterContainer& parameters )
 {
    String elementType;
@@ -368,14 +441,14 @@ bool setElementType( const MeshPointer& meshPointer,
       return setIndexType< MeshPointer, double, double >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( elementType == "long double" )
       return setIndexType< MeshPointer, long double, long double >( meshPointer, inputFileName, parsedObjectType, parameters );
-   List< String > parsedElementType;
+   Containers::List< String > parsedElementType;
    if( ! parseObjectType( elementType, parsedElementType ) )
    {
       std::cerr << "Unable to parse object type " << elementType << "." << std::endl;
       return false;
    }
    if( parsedElementType[ 0 ] == "Containers::StaticVector" ||
-       parsedElementType[ 0 ] == "tnlStaticVector" )               // TODO: remove deprecated type names
+       parsedElementType[ 0 ] == "Containers::StaticVector" )               // TODO: remove deprecated type names
       return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedElementType, parameters );
 
    std::cerr << "Unknown element type " << elementType << "." << std::endl;
@@ -400,7 +473,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
    meshPointer->writeMesh( "mesh.asy", "asymptote" );
 
    bool checkOutputFile = parameters. getParameter< bool >( "check-output-file" );
-   List< String > inputFiles = parameters. getParameter< List< String > >( "input-files" );
+   Containers::List< String > inputFiles = parameters. getParameter< Containers::List< String > >( "input-files" );
    bool error( false );
 //#ifdef HAVE_OPENMP
 //#pragma omp parallel for
@@ -434,7 +507,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
          if( verbose )
            std::cout << objectType << " detected ... ";
 
-         List< String > parsedObjectType;
+         Containers::List< String > parsedObjectType;
          if( ! parseObjectType( objectType, parsedObjectType ) )
          {
             std::cerr << "Unable to parse object type " << objectType << "." << std::endl;
@@ -451,6 +524,8 @@ bool processFiles( const Config::ParameterContainer& parameters )
          if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ||
              parsedObjectType[ 0 ] == "tnlMeshFunction" )                     // TODO: remove deprecated type names
             setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
+         if( parsedObjectType[ 0 ] == "Functions::VectorField" )
+            setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
          if( verbose )
            std::cout << "[ OK ].  " << std::endl;
       }
diff --git a/src/Tools/tnlcurve2gnuplot.cpp b/src/Tools/tnlcurve2gnuplot.cpp
index baea729a13a36d63fc0d7bd86ac9287e91c35af4..5a1e297d60973b8a1a6f8f7f053732cdcce9fb0c 100644
--- a/src/Tools/tnlcurve2gnuplot.cpp
+++ b/src/Tools/tnlcurve2gnuplot.cpp
@@ -36,9 +36,9 @@ int main( int argc, char* argv[] )
       return 1;
    }
 
-   List< String > input_files = parameters. getParameter< List< String > >( "input-files" );
-   List< String > output_files;
-   if( ! parameters. getParameter< List< String > >( "output-files", output_files ) )
+   Containers::List< String > input_files = parameters. getParameter< Containers::List< String > >( "input-files" );
+   Containers::List< String > output_files;
+   if( ! parameters. getParameter< Containers::List< String > >( "output-files", output_files ) )
       std::cout << "No output files were given." << std::endl;
    int output_step( 1 );
    parameters. getParameter< int >( "output-step", output_step );
@@ -58,7 +58,7 @@ int main( int argc, char* argv[] )
       std::cout << "Processing file " << input_file << " ... " << std::flush;
  
       File file;
-      if( ! file. open( input_files[ i ], tnlReadMode ) )
+      if( ! file. open( input_files[ i ], IOMode::read ) )
       {
          std::cout << " unable to open file " << input_files[ i ] << std::endl;
          continue;
diff --git a/src/UnitTests/CMakeLists.txt b/src/UnitTests/CMakeLists.txt
old mode 100755
new mode 100644
index ac80ff9471a888c101a4d4f699eb04c1734e3427..f702830a06cc20b76171ec10fffbe9a89711cce4
--- a/src/UnitTests/CMakeLists.txt
+++ b/src/UnitTests/CMakeLists.txt
@@ -1,39 +1,43 @@
-#ADD_SUBDIRECTORY( Containers )
+if( WITH_TESTS STREQUAL "yes" )
 
-ADD_EXECUTABLE( UniquePointerTest${mpiExt}${debugExt} ${headers} UniquePointerTest.cpp )
-SET_TARGET_PROPERTIES( UniquePointerTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-TARGET_LINK_LIBRARIES( UniquePointerTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+ADD_SUBDIRECTORY( Containers )
+ADD_SUBDIRECTORY( Matrices )
+
+ADD_EXECUTABLE( UniquePointerTest${mpiExt}${debugExt} UniquePointerTest.cpp )
+TARGET_COMPILE_OPTIONS( UniquePointerTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( UniquePointerTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES}
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
 
 IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( FileTest${mpiExt}${debugExt} FileTest.h FileTest.cu )
-   SET_TARGET_PROPERTIES( FileTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( FileTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+   CUDA_ADD_EXECUTABLE( FileTest${mpiExt}${debugExt} FileTest.cu OPTIONS ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( FileTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
 ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( FileTest${mpiExt}${debugExt} FileTest.h FileTest.cpp )
-   SET_TARGET_PROPERTIES( FileTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( FileTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+   ADD_EXECUTABLE( FileTest${mpiExt}${debugExt} FileTest.cpp )
+   TARGET_COMPILE_OPTIONS( FileTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( FileTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
 ENDIF( BUILD_CUDA )
 
-ADD_EXECUTABLE( StringTest${mpiExt}${debugExt} ${headers} StringTest.cpp )
-SET_TARGET_PROPERTIES( StringTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-TARGET_LINK_LIBRARIES( StringTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-
-ADD_EXECUTABLE( ListTest${mpiExt}${debugExt} ${headers} ListTest.cpp )
-SET_TARGET_PROPERTIES( ListTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-TARGET_LINK_LIBRARIES( ListTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+ADD_EXECUTABLE( StringTest${mpiExt}${debugExt} StringTest.cpp )
+TARGET_COMPILE_OPTIONS( StringTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( StringTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES}
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-ADD_EXECUTABLE( ObjectTest${mpiExt}${debugExt} ${headers} ObjectTest.cpp )
-SET_TARGET_PROPERTIES( ObjectTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-TARGET_LINK_LIBRARIES( ObjectTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES} 
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+ADD_EXECUTABLE( ObjectTest${mpiExt}${debugExt} ObjectTest.cpp )
+TARGET_COMPILE_OPTIONS( ObjectTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( ObjectTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES} 
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
 
 
 ADD_TEST( FileTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/FileTest${mpiExt}${debugExt} )
 ADD_TEST( StringTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/StringTest${mpiExt}${debugExt} )
-ADD_TEST( ListTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ListTest${mpiExt}${debugExt} )
-ADD_TEST( ObjectTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ObjectTest${mpiExt}${debugExt} )
\ No newline at end of file
+ADD_TEST( ObjectTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ObjectTest${mpiExt}${debugExt} )
+ADD_TEST( UniquePointerTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/UniquePointerTest${mpiExt}${debugExt} )
+
+endif( WITH_TESTS STREQUAL "yes" )
diff --git a/src/UnitTests/Containers/ArrayOperationsTest.cpp b/src/UnitTests/Containers/ArrayOperationsTest.cpp
index 92c24428b74513d8bda61db2fe5095a7d4e4ff8a..c499a61b2cb1b50eebf9fc7fedacf56b9c7cb68a 100644
--- a/src/UnitTests/Containers/ArrayOperationsTest.cpp
+++ b/src/UnitTests/Containers/ArrayOperationsTest.cpp
@@ -9,5 +9,3 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include "ArrayOperationsTest.h"
-
-
diff --git a/src/UnitTests/Containers/ArrayOperationsTest.h b/src/UnitTests/Containers/ArrayOperationsTest.h
index 796f5b6e69f651c4755c55e1b0696550b14ac481..be75e04fe737e6cb4c4ac032af3656c48623211e 100644
--- a/src/UnitTests/Containers/ArrayOperationsTest.h
+++ b/src/UnitTests/Containers/ArrayOperationsTest.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ArrayOperationsTester.h  -  description
+                          ArrayOperationsTest.h  -  description
                              -------------------
     begin                : Jul 15, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -10,303 +10,310 @@
 
 #pragma once
 
-#include <TNL/Containers/ArrayOperations.h>
+#ifdef HAVE_GTEST 
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Devices/Cuda.h>
 
-#ifdef HAVE_GTEST 
 #include "gtest/gtest.h"
-#endif
 
 using namespace TNL;
 using namespace TNL::Containers;
+using namespace TNL::Containers::Algorithms;
+
+constexpr int ARRAY_TEST_SIZE = 5000;
 
-int getTestSize()
+// test fixture for typed tests
+template< typename Element >
+class ArrayOperationsTest : public ::testing::Test
 {
-   return 1 << 16;
-   //const int cudaGridSize = 256;
-   //return 1.5 * cudaGridSize * maxCudaBlockSize;
-   //return  1 << 22;
+protected:
+   using ElementType = Element;
 };
 
-typedef int Element;
+// types for which ArrayTest is instantiated
+using ElementTypes = ::testing::Types< short int, int, long, float, double >;
 
-#ifdef HAVE_GTEST
+TYPED_TEST_CASE( ArrayOperationsTest, ElementTypes );
 
-TEST( ArrayOperationsTest, allocationTest )
+TYPED_TEST( ArrayOperationsTest, allocateMemory_host )
 {
-   Element* data;
-   ArrayOperations< Devices::Host >::allocateMemory( data, getTestSize() );
-   ASSERT_EQ( data, ( Element* ) NULL );
+   using ElementType = typename TestFixture::ElementType;
+
+   ElementType* data;
+   ArrayOperations< Devices::Host >::allocateMemory( data, ARRAY_TEST_SIZE );
+   ASSERT_NE( data, nullptr );
 
    ArrayOperations< Devices::Host >::freeMemory( data );
-};
+}
 
-TEST( ArrayOperationsTest, memorySetTest )
+TYPED_TEST( ArrayOperationsTest, setMemoryElement_host )
 {
-   const int size = 1024;
-   Element *data;
-   ArrayOperations< Devices::Host > :: allocateMemory( data, size );
-   ArrayOperations< Devices::Host > :: setMemory( data, 13, size );
-   for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( data[ i ], 13 );
-   ArrayOperations< Devices::Host > :: freeMemory( data );
-};
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
+   ElementType *data;
+   ArrayOperations< Devices::Host >::allocateMemory( data, size );
+   for( int i = 0; i < size; i++ ) {
+      ArrayOperations< Devices::Host >::setMemoryElement( data + i, (ElementType) i );
+      EXPECT_EQ( data[ i ], i );
+      EXPECT_EQ( ArrayOperations< Devices::Host >::getMemoryElement( data + i ), i );
+   }
+   ArrayOperations< Devices::Host >::freeMemory( data );
+}
 
-TEST( ArrayOperationsTest, copyMemoryTest )
+TYPED_TEST( ArrayOperationsTest, setMemory_host )
 {
-   const int size = getTestSize();
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
 
-   Element *data1, *data2;
-   ArrayOperations< Devices::Host > :: allocateMemory( data1, size );
-   ArrayOperations< Devices::Host > :: allocateMemory( data2, size );
-   ArrayOperations< Devices::Host > :: setMemory( data1, 13, size );
-   ArrayOperations< Devices::Host > :: copyMemory< Element, Element, int >( data2, data1, size );
+   ElementType *data;
+   ArrayOperations< Devices::Host >::allocateMemory( data, size );
+   ArrayOperations< Devices::Host >::setMemory( data, (ElementType) 13, size );
    for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( data1[ i ], data2[ i ]);
-   ArrayOperations< Devices::Host > :: freeMemory( data1 );
-   ArrayOperations< Devices::Host > :: freeMemory( data2 );
-};
+      EXPECT_EQ( data[ i ], 13 );
+   ArrayOperations< Devices::Host >::freeMemory( data );
+}
+
+TYPED_TEST( ArrayOperationsTest, copyMemory_host )
+{
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
+   ElementType *data1, *data2;
+   ArrayOperations< Devices::Host >::allocateMemory( data1, size );
+   ArrayOperations< Devices::Host >::allocateMemory( data2, size );
+   ArrayOperations< Devices::Host >::setMemory( data1, (ElementType) 13, size );
+   ArrayOperations< Devices::Host >::copyMemory< ElementType, ElementType >( data2, data1, size );
+   for( int i = 0; i < size; i ++ )
+      EXPECT_EQ( data1[ i ], data2[ i ]);
+   ArrayOperations< Devices::Host >::freeMemory( data1 );
+   ArrayOperations< Devices::Host >::freeMemory( data2 );
+}
 
-TEST( ArrayOperationsTest, copyMemoryWithConversionTest )
+TYPED_TEST( ArrayOperationsTest, copyMemoryWithConversion_host )
 {
-   const int size = getTestSize();
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
    int *data1;
    float *data2;
-   ArrayOperations< Devices::Host > :: allocateMemory( data1, size );
-   ArrayOperations< Devices::Host > :: allocateMemory( data2, size );
-   ArrayOperations< Devices::Host > :: setMemory( data1, 13, size );
-   ArrayOperations< Devices::Host > :: copyMemory< float, int, int >( data2, data1, size );
+   ArrayOperations< Devices::Host >::allocateMemory( data1, size );
+   ArrayOperations< Devices::Host >::allocateMemory( data2, size );
+   ArrayOperations< Devices::Host >::setMemory( data1, 13, size );
+   ArrayOperations< Devices::Host >::copyMemory< float, int >( data2, data1, size );
    for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( data1[ i ], data2[ i ] );
-   ArrayOperations< Devices::Host > :: freeMemory( data1 );
-   ArrayOperations< Devices::Host > :: freeMemory( data2 );
-};
+      EXPECT_EQ( data1[ i ], data2[ i ] );
+   ArrayOperations< Devices::Host >::freeMemory( data1 );
+   ArrayOperations< Devices::Host >::freeMemory( data2 );
+}
 
-TEST( ArrayOperationsTest, compareMemoryTest )
+TYPED_TEST( ArrayOperationsTest, compareMemory_host )
 {
-   const int size = getTestSize();
-   int *data1, *data2;
-   ArrayOperations< Devices::Host > :: allocateMemory( data1, size );
-   ArrayOperations< Devices::Host > :: allocateMemory( data2, size );
-   ArrayOperations< Devices::Host > :: setMemory( data1, 7, size );
-   ASSERT_FALSE( ( ArrayOperations< Devices::Host > :: compareMemory< int, int, int >( data1, data2, size ) ) );
-   ArrayOperations< Devices::Host > :: setMemory( data2, 7, size );
-   ASSERT_TRUE( ( ArrayOperations< Devices::Host > :: compareMemory< int, int, int >( data1, data2, size ) ) );
-};
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
+   ElementType *data1, *data2;
+   ArrayOperations< Devices::Host >::allocateMemory( data1, size );
+   ArrayOperations< Devices::Host >::allocateMemory( data2, size );
+   ArrayOperations< Devices::Host >::setMemory( data1, (ElementType) 7, size );
+   ArrayOperations< Devices::Host >::setMemory( data2, (ElementType) 0, size );
+   EXPECT_FALSE( ( ArrayOperations< Devices::Host >::compareMemory< ElementType, ElementType >( data1, data2, size ) ) );
+   ArrayOperations< Devices::Host >::setMemory( data2, (ElementType) 7, size );
+   EXPECT_TRUE( ( ArrayOperations< Devices::Host >::compareMemory< ElementType, ElementType >( data1, data2, size ) ) );
+   ArrayOperations< Devices::Host >::freeMemory( data1 );
+   ArrayOperations< Devices::Host >::freeMemory( data2 );
+}
 
-TEST( ArrayOperationsTest, compareMemoryWithConversionTest )
+TYPED_TEST( ArrayOperationsTest, compareMemoryWithConversion_host )
 {
-   const int size = getTestSize();
+   const int size = ARRAY_TEST_SIZE;
+
    int *data1;
    float *data2;
-   ArrayOperations< Devices::Host > :: allocateMemory( data1, size );
-   ArrayOperations< Devices::Host > :: allocateMemory( data2, size );
-   ArrayOperations< Devices::Host > :: setMemory( data1, 7, size );
-   ASSERT_FALSE( ( ArrayOperations< Devices::Host > :: compareMemory< int, float, int >( data1, data2, size ) ) );
-   ArrayOperations< Devices::Host > :: setMemory( data2, ( float ) 7.0, size );
-   ASSERT_TRUE( ( ArrayOperations< Devices::Host > :: compareMemory< int, float, int >( data1, data2, size ) ) );
-};
+   ArrayOperations< Devices::Host >::allocateMemory( data1, size );
+   ArrayOperations< Devices::Host >::allocateMemory( data2, size );
+   ArrayOperations< Devices::Host >::setMemory( data1, 7, size );
+   ArrayOperations< Devices::Host >::setMemory( data2, (float) 0.0, size );
+   EXPECT_FALSE( ( ArrayOperations< Devices::Host >::compareMemory< int, float >( data1, data2, size ) ) );
+   ArrayOperations< Devices::Host >::setMemory( data2, (float) 7.0, size );
+   EXPECT_TRUE( ( ArrayOperations< Devices::Host >::compareMemory< int, float >( data1, data2, size ) ) );
+   ArrayOperations< Devices::Host >::freeMemory( data1 );
+   ArrayOperations< Devices::Host >::freeMemory( data2 );
+}
 
 
 #ifdef HAVE_CUDA
-TEST( ArrayOperationsTest, allocationTest )
+TYPED_TEST( ArrayOperationsTest, allocateMemory_cuda )
 {
-   int* data;
-   ArrayOperations< Devices::Cuda >::allocateMemory( data, getTestSize() );
-   ASSERT_TRUE( checkCudaDevice );
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
 
-   ArrayOperations< Devices::Cuda >::freeMemory( data );
-   ASSERT_TRUE( checkCudaDevice );
-}
-
-TEST( ArrayOperationsTest, setMemoryElementTest )
-{
-   const int size( 1024 );
-   int* data;
+   ElementType* data;
    ArrayOperations< Devices::Cuda >::allocateMemory( data, size );
-   ASSERT_TRUE( checkCudaDevice );
-
-   for( int i = 0; i < getTestSize(); i++ )
-      ArrayOperations< Devices::Cuda >::setMemoryElement( &data[ i ], i );
-
-   for( int i = 0; i < size; i++ )
-   {
-      int d;
-      ASSERT_EQ( cudaMemcpy( &d, &data[ i ], sizeof( int ), cudaMemcpyDeviceToHost ), cudaSuccess );
-      ASSERT_EQ( d, i );
-   }
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
+   ASSERT_NE( data, nullptr );
 
    ArrayOperations< Devices::Cuda >::freeMemory( data );
-   ASSERT_TRUE( checkCudaDevice );
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
 }
 
-TEST( ArrayOperationsTest, getMemoryElementTest )
+TYPED_TEST( ArrayOperationsTest, setMemoryElement_cuda )
 {
-   const int size( 1024 );
-   int* data;
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
+   ElementType* data;
    ArrayOperations< Devices::Cuda >::allocateMemory( data, size );
-   ASSERT_TRUE( checkCudaDevice );
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
 
-   for( int i = 0; i < getTestSize(); i++ )
-      ArrayOperations< Devices::Cuda >::setMemoryElement( &data[ i ], i );
+   for( int i = 0; i < size; i++ )
+      ArrayOperations< Devices::Cuda >::setMemoryElement( &data[ i ], (ElementType) i );
 
    for( int i = 0; i < size; i++ )
-      ASSERT_EQ( ( ArrayOperations< Devices::Cuda >::getMemoryElement( &data[ i ] ), i ) );
+   {
+      ElementType d;
+      ASSERT_EQ( cudaMemcpy( &d, &data[ i ], sizeof( ElementType ), cudaMemcpyDeviceToHost ), cudaSuccess );
+      EXPECT_EQ( d, i );
+      EXPECT_EQ( ArrayOperations< Devices::Cuda >::getMemoryElement( &data[ i ] ), i );
+   }
 
    ArrayOperations< Devices::Cuda >::freeMemory( data );
-   ASSERT_TRUE( checkCudaDevice );
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
 }
 
-
-TEST( ArrayOperationsTest, smallMemorySetTest )
+TYPED_TEST( ArrayOperationsTest, setMemory_cuda )
 {
-   const int size = 1024;
-   int *hostData, *deviceData;
-   ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
-   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData, 0, size );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, 13, size );
-   ASSERT_TRUE( checkCudaDevice );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< int, int >( hostData, deviceData, size );
-   ASSERT_TRUE( checkCudaDevice );
-   for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( hostData[ i ], 13 );
-   ArrayOperations< Devices::Cuda >::freeMemory( hostData );
-   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-};
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
 
-TEST( ArrayOperationsTest, bigMemorySetTest )
-{
-   const int size( getTestSize() );
-   int *hostData, *deviceData;
+   ElementType *hostData, *deviceData;
    ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData, 0, size );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, 13, size );
-   ASSERT_TRUE( checkCudaDevice );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< int, int >( hostData, deviceData, size );
-   ASSERT_TRUE( checkCudaDevice );
-   for( int i = 0; i < size; i += 100 )
-   {
-      if( hostData[ i ] != 13 )
-      ASSERT_EQ( hostData[ i ], 13 );
-   }
+   ArrayOperations< Devices::Host >::setMemory( hostData, (ElementType) 0, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData, (ElementType) 13, size );
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
+   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< ElementType, ElementType >( hostData, deviceData, size );
+   ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( hostData[ i ], 13 );
    ArrayOperations< Devices::Host >::freeMemory( hostData );
    ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-};
+}
 
-TEST( ArrayOperationsTest, copyMemoryTest )
+TYPED_TEST( ArrayOperationsTest, copyMemory_cuda )
 {
-   const int size = getTestSize();
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
 
-   int *hostData1, *hostData2, *deviceData;
-   ArrayOperations< Devices::Host >::allocateMemory( hostData1, size );
+   ElementType *hostData, *hostData2, *deviceData, *deviceData2;
+   ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
    ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData1, 13, size );
-   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< int, int >( deviceData, hostData1, size );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< int, int >( hostData2, deviceData, size );
-   ASSERT_TRUE( ( ArrayOperations< Devices::Host >::compareMemory< int, int >( hostData1, hostData2, size) ) );
-   ArrayOperations< Devices::Host >::freeMemory( hostData1 );
+   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
+   ArrayOperations< Devices::Host >::setMemory( hostData, (ElementType) 13, size );
+   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< ElementType >( deviceData, hostData, size );
+   ArrayOperations< Devices::Cuda >::copyMemory< ElementType, ElementType >( deviceData2, deviceData, size );
+   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< ElementType, ElementType >( hostData2, deviceData2, size );
+   EXPECT_TRUE( ( ArrayOperations< Devices::Host >::compareMemory< ElementType, ElementType >( hostData, hostData2, size) ) );
+   ArrayOperations< Devices::Host >::freeMemory( hostData );
    ArrayOperations< Devices::Host >::freeMemory( hostData2 );
    ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-};
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData2 );
+}
 
-TEST( ArrayOperationsTest, copyMemoryWithConversionHostToCudaTest )
+TYPED_TEST( ArrayOperationsTest, copyMemoryWithConversions_cuda )
 {
-   const int size = getTestSize();
-   int *hostData1;
-   float *hostData2, *deviceData;
-   ArrayOperations< Devices::Host >::allocateMemory( hostData1, size );
-   ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
-   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData1, 13, size );
-   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< float, int, int >( deviceData, hostData1, size );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< float, float, int >( hostData2, deviceData, size );
-   for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( hostData1[ i ], hostData2[ i ] );
-   ArrayOperations< Devices::Host >::freeMemory( hostData1 );
-   ArrayOperations< Devices::Host >::freeMemory( hostData2 );
-   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-};
+   const int size = ARRAY_TEST_SIZE;
 
-TEST( ArrayOperationsTest, copyMemoryWithConversionCudaToHostTest )
-{
-   const int size = getTestSize();
-   int *hostData1, *deviceData;
-   float *hostData2;
-   ArrayOperations< Devices::Host >::allocateMemory( hostData1, size );
+   int *hostData;
+   double *hostData2;
+   long *deviceData;
+   float *deviceData2;
+   ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
    ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData1, 13, size );
-   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< int, int >( deviceData, hostData1, size );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< float, int, int >( hostData2, deviceData, size );
-   for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( hostData1[ i ], hostData2[ i ] );
-   ArrayOperations< Devices::Host >::freeMemory( hostData1 );
-   ArrayOperations< Devices::Host >::freeMemory( hostData2 );
-   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-};
-
-TEST( ArrayOperationsTest, copyMemoryWithConversionCudaToCudaTest )
-{
-   const int size = getTestSize();
-   int *hostData1, *deviceData1;
-   float *hostData2, *deviceData2;
-   ArrayOperations< Devices::Host >::allocateMemory( hostData1, size );
-   ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
-   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData1, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData1, 13, size );
-   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< int, int, int >( deviceData1, hostData1, size );
-   ArrayOperations< Devices::Cuda >::copyMemory< float, int, int >( deviceData2, deviceData1, size );
-   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< float, float, int >( hostData2, deviceData2, size );
+   ArrayOperations< Devices::Host >::setMemory( hostData, 13, size );
+   ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< long, int >( deviceData, hostData, size );
+   ArrayOperations< Devices::Cuda >::copyMemory< float, long >( deviceData2, deviceData, size );
+   ArrayOperations< Devices::Host, Devices::Cuda >::copyMemory< double, float >( hostData2, deviceData2, size );
    for( int i = 0; i < size; i ++ )
-      ASSERT_EQ( hostData1[ i ], hostData2[ i ] );
-   ArrayOperations< Devices::Host >::freeMemory( hostData1 );
+      EXPECT_EQ( hostData[ i ], hostData2[ i ] );
+   ArrayOperations< Devices::Host >::freeMemory( hostData );
    ArrayOperations< Devices::Host >::freeMemory( hostData2 );
-   ArrayOperations< Devices::Cuda >::freeMemory( deviceData1 );
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
    ArrayOperations< Devices::Cuda >::freeMemory( deviceData2 );
-};
+}
 
-TEST( ArrayOperationsTest, compareMemoryHostCudaTest )
+TYPED_TEST( ArrayOperationsTest, compareMemory_cuda )
 {
-   const int size = getTestSize();
-   int *hostData, *deviceData;
+   using ElementType = typename TestFixture::ElementType;
+   const int size = ARRAY_TEST_SIZE;
+
+   ElementType *hostData, *deviceData, *deviceData2;
    ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-   ArrayOperations< Devices::Host >::setMemory( hostData, 7, size );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, 8, size );
-   ASSERT_FALSE( ( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, int, int >( hostData, deviceData, size ) ) );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, 7, size );
-   ASSERT_TRUE( ( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, int, int >( hostData, deviceData, size ) ) );
-};
+   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
+
+   ArrayOperations< Devices::Host >::setMemory( hostData, (ElementType) 7, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData, (ElementType) 8, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData2, (ElementType) 9, size );
+   EXPECT_FALSE(( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< ElementType, ElementType >( hostData, deviceData, size ) ));
+   EXPECT_FALSE(( ArrayOperations< Devices::Cuda, Devices::Host >::compareMemory< ElementType, ElementType >( deviceData, hostData, size ) ));
+   EXPECT_FALSE(( ArrayOperations< Devices::Cuda >::compareMemory< ElementType, ElementType >( deviceData, deviceData2, size ) ));
+
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData, (ElementType) 7, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData2, (ElementType) 7, size );
+   EXPECT_TRUE(( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< ElementType, ElementType >( hostData, deviceData, size ) ));
+   EXPECT_TRUE(( ArrayOperations< Devices::Cuda, Devices::Host >::compareMemory< ElementType, ElementType >( deviceData, hostData, size ) ));
+   EXPECT_TRUE(( ArrayOperations< Devices::Cuda >::compareMemory< ElementType, ElementType >( deviceData, deviceData2, size ) ));
 
-TEST( ArrayOperationsTest, compareMemoryWithConversionHostCudaTest )
+   ArrayOperations< Devices::Host >::freeMemory( hostData );
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData2 );
+}
+
+TYPED_TEST( ArrayOperationsTest, compareMemoryWithConversions_cuda )
 {
-   const int size = getTestSize();
+   const int size = ARRAY_TEST_SIZE;
+
    int *hostData;
    float *deviceData;
+   double *deviceData2;
    ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
    ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
+   ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
+
    ArrayOperations< Devices::Host >::setMemory( hostData, 7, size );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, ( float ) 8.0, size );
-   ASSERT_FALSE( ( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, float, int >( hostData, deviceData, size ) ) );
-   ArrayOperations< Devices::Cuda >::setMemory( deviceData, ( float ) 7.0, size );
-   ASSERT_TRUE( ( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, float, int >( hostData, deviceData, size ) ) );
-};
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData, (float) 8, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData2, (double) 9, size );
+   EXPECT_FALSE(( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, float >( hostData, deviceData, size ) ));
+   EXPECT_FALSE(( ArrayOperations< Devices::Cuda, Devices::Host >::compareMemory< float, int >( deviceData, hostData, size ) ));
+   // TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_FALSE(( ArrayOperations< Devices::Cuda >::compareMemory< float, double >( deviceData, deviceData2, size ) ));
+
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData, (float) 7, size );
+   ArrayOperations< Devices::Cuda >::setMemory( deviceData2, (double) 7, size );
+   EXPECT_TRUE(( ArrayOperations< Devices::Host, Devices::Cuda >::compareMemory< int, float >( hostData, deviceData, size ) ));
+   EXPECT_TRUE(( ArrayOperations< Devices::Cuda, Devices::Host >::compareMemory< float, int >( deviceData, hostData, size ) ));
+   // TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_TRUE(( ArrayOperations< Devices::Cuda >::compareMemory< float, double >( deviceData, deviceData2, size ) ));
+
+   ArrayOperations< Devices::Host >::freeMemory( hostData );
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
+   ArrayOperations< Devices::Cuda >::freeMemory( deviceData2 );
+}
 #endif // HAVE_CUDA
 #endif // HAVE_GTEST
 
+
+#include "../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
-
-
-
diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h
index a930efdbb5e5c15b8fb317c21879864d4e5b1d12..cd7959b5ff477bb70c1c7be8206e3fc46c38c1f3 100644
--- a/src/UnitTests/Containers/ArrayTest.h
+++ b/src/UnitTests/Containers/ArrayTest.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          ArrayTester.h -  description
+                          ArrayTest.h -  description
                              -------------------
     begin                : Jul 4, 2012
     copyright            : (C) 2012 by Tomas Oberhuber
@@ -10,255 +10,562 @@
 
 #pragma once
 
+#ifdef HAVE_GTEST 
+#include <type_traits>
+
 #include <TNL/Containers/Array.h>
-#include <TNL/Devices/Host.h>
 
-#ifdef HAVE_GTEST 
 #include "gtest/gtest.h"
-#endif
 
 using namespace TNL;
 using namespace TNL::Containers;
 
-#ifdef HAVE_CUDA
-template< typename ElementType, typename IndexType >
-__global__ void testSetGetElementKernel( Array< ElementType, Devices::Cuda, IndexType >* u );
-#endif
-
-class testingClassForArrayTester
+// minimal custom data structure usable as ElementType in Array
+struct MyData
 {
-   public:
+   double data;
+
+   __cuda_callable__
+   MyData() : data(0) {}
+
+   template< typename T >
+   __cuda_callable__
+   MyData( T v ) : data(v) {}
 
-      static String getType()
-      {
-         return String( "testingClassForArrayTester" );
-      };
+   bool operator==( const MyData& v ) const { return data == v.data; }
+
+   // operator used in tests, not necessary for Array to work
+   template< typename T >
+   bool operator==( T v ) const { return data == v; }
+
+   static String getType()
+   {
+      return String( "MyData" );
+   }
 };
 
-String getType( const testingClassForArrayTester& c )
+std::ostream& operator<<( std::ostream& str, const MyData& v )
 {
-   return String( "testingClassForArrayTester" );
-};
+   return str << v.data;
+}
 
-#ifdef HAVE_GTEST
 
+// test fixture for typed tests
+template< typename Array >
+class ArrayTest : public ::testing::Test
+{
+protected:
+   using ArrayType = Array;
+};
 
-// TODO: Fix this
-#if GTEST_HAS_TYPED_TEST
+// types for which ArrayTest is instantiated
+using ArrayTypes = ::testing::Types<
+   Array< short,  Devices::Host, short >,
+   Array< int,    Devices::Host, short >,
+   Array< long,   Devices::Host, short >,
+   Array< float,  Devices::Host, short >,
+   Array< double, Devices::Host, short >,
+   Array< MyData, Devices::Host, short >,
+   Array< short,  Devices::Host, int >,
+   Array< int,    Devices::Host, int >,
+   Array< long,   Devices::Host, int >,
+   Array< float,  Devices::Host, int >,
+   Array< double, Devices::Host, int >,
+   Array< MyData, Devices::Host, int >,
+   Array< short,  Devices::Host, long >,
+   Array< int,    Devices::Host, long >,
+   Array< long,   Devices::Host, long >,
+   Array< float,  Devices::Host, long >,
+   Array< double, Devices::Host, long >,
+   Array< MyData, Devices::Host, long >
+   // FIXME: this segfaults in String::~String()
+//   , Array< String, Devices::Host, long >
+#ifdef HAVE_CUDA
+   ,
+   Array< short,  Devices::Cuda, short >,
+   Array< int,    Devices::Cuda, short >,
+   Array< long,   Devices::Cuda, short >,
+   Array< float,  Devices::Cuda, short >,
+   Array< double, Devices::Cuda, short >,
+   Array< MyData, Devices::Cuda, short >,
+   Array< short,  Devices::Cuda, int >,
+   Array< int,    Devices::Cuda, int >,
+   Array< long,   Devices::Cuda, int >,
+   Array< float,  Devices::Cuda, int >,
+   Array< double, Devices::Cuda, int >,
+   Array< MyData, Devices::Cuda, int >,
+   Array< short,  Devices::Cuda, long >,
+   Array< int,    Devices::Cuda, long >,
+   Array< long,   Devices::Cuda, long >,
+   Array< float,  Devices::Cuda, long >,
+   Array< double, Devices::Cuda, long >,
+   Array< MyData, Devices::Cuda, long >
+#endif
+#ifdef HAVE_MIC
+   ,
+   Array< short,  Devices::MIC, short >,
+   Array< int,    Devices::MIC, short >,
+   Array< long,   Devices::MIC, short >,
+   Array< float,  Devices::MIC, short >,
+   Array< double, Devices::MIC, short >,
+   // TODO: MyData does not work on MIC
+//   Array< MyData, Devices::MIC, short >,
+   Array< short,  Devices::MIC, int >,
+   Array< int,    Devices::MIC, int >,
+   Array< long,   Devices::MIC, int >,
+   Array< float,  Devices::MIC, int >,
+   Array< double, Devices::MIC, int >,
+   // TODO: MyData does not work on MIC
+//   Array< MyData, Devices::MIC, int >,
+   Array< short,  Devices::MIC, long >,
+   Array< int,    Devices::MIC, long >,
+   Array< long,   Devices::MIC, long >,
+   Array< float,  Devices::MIC, long >,
+   Array< double, Devices::MIC, long >
+   // TODO: MyData does not work on MIC
+//   Array< MyData, Devices::MIC, long >
+#endif
+>;
+
+TYPED_TEST_CASE( ArrayTest, ArrayTypes );
 
-using ::testing::Types;
-typedef Types< int, Devices::Host, int > MyTypes;
-/*TYPED_TEST_CASE( ArrayTest, MyTypes );
 
-TYPED_TEST( ArrayTest, testConstructorDestructor )
+TYPED_TEST( ArrayTest, constructors )
 {
-   typedef Array< TypeParam > ArrayType;
+   using ArrayType = typename TestFixture::ArrayType;
+
    ArrayType u;
+   EXPECT_EQ( u.getSize(), 0 );
+
    ArrayType v( 10 );
-   ASSERT_EQ( v.getSize(), 10 );
+   EXPECT_EQ( v.getSize(), 10 );
+
+   if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) {
+      typename ArrayType::ElementType data[ 10 ];
+      ArrayType w( data, 10 );
+      EXPECT_EQ( w.getData(), data );
+
+      ArrayType z1( w );
+      EXPECT_EQ( z1.getData(), data );
+      EXPECT_EQ( z1.getSize(), 10 );
+
+      ArrayType z2( w, 1 );
+      EXPECT_EQ( z2.getData(), data + 1 );
+      EXPECT_EQ( z2.getSize(), 9 );
+
+      ArrayType z3( w, 2, 3 );
+      EXPECT_EQ( z3.getData(), data + 2 );
+      EXPECT_EQ( z3.getSize(), 3 );
+   }
 }
 
-TYPED_TEST( ArrayTest, testSetSize )
+TYPED_TEST( ArrayTest, setSize )
 {
-   typedef Array< TypeParam > ArrayType;
-   ArrayType u, v;
-   u.setSize( 10 );
-   v.setSize( 10 );
-   ASSERT_EQ( u.getSize(), 10 );
-   ASSERT_EQ( v.getSize(), 10 );
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u;
+   const int maxSize = 10;
+   for( int i = 0; i <= maxSize; i ++ ) {
+      u.setSize( i );
+      EXPECT_EQ( u.getSize(), i );
+   }
+
+   ArrayType v( u );
+   EXPECT_EQ( v.getSize(), 10 );
+   EXPECT_EQ( v.getData(), u.getData() );
+   v.setSize( 11 );
+   EXPECT_EQ( u.getSize(), 10 );
+   EXPECT_EQ( v.getSize(), 11 );
+   EXPECT_NE( v.getData(), u.getData() );
+
+   // cast to bool returns true iff size > 0
+   EXPECT_TRUE( (bool) u );
+   EXPECT_FALSE( ! u );
+   u.setSize( 0 );
+   EXPECT_FALSE( (bool) u );
+   EXPECT_TRUE( ! u );
 }
 
-TYPED_TEST( ArrayTest, testBind )
+TYPED_TEST( ArrayTest, setLike )
 {
-   typedef Array< TypeParam > ArrayType;
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u( 10 );
+   EXPECT_EQ( u.getSize(), 10 );
+
+   ArrayType v;
+   v.setLike( u );
+   EXPECT_EQ( v.getSize(), u.getSize() );
+   EXPECT_NE( v.getData(), u.getData() );
+}
+
+TYPED_TEST( ArrayTest, bind )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
    ArrayType u( 10 ), v;
-   u.setValue( 27 );
    v.bind( u );
-   ASSERT_EQ( v.getSize(), u.getSize() );
-   ASSERT_EQ( u.getElement( 0 ), 27 );
-   v.setValue( 50 );
-   ASSERT_EQ( u.getElement( 0 ), 50 );
-   u.reset();
-   ASSERT_EQ( u.getSize(), 0 );
-   ASSERT_EQ( v.getElement( 0 ), 50 );
+   EXPECT_EQ( v.getSize(), u.getSize() );
+   EXPECT_EQ( v.getData(), u.getData() );
 
-   ElementType data[ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
-   u.bind( data, 10 );
-   ASSERT_EQ( u.getElement( 1 ), 2 );
-   v.bind( u );
-   ASSERT_EQ( v.getElement( 1 ), 2 );
+   // bind array with offset and size
+   ArrayType w;
+   w.bind( u, 2, 3 );
+   EXPECT_EQ( w.getSize(), 3 );
+   EXPECT_EQ( w.getData(), u.getData() + 2 );
+
+   // setting values
+   u.setValue( 27 );
+   EXPECT_EQ( u.getElement( 0 ), 27 );
+   v.setValue( 50 );
+   EXPECT_EQ( u.getElement( 0 ), 50 );
    u.reset();
-   v.setElement( 1, 3 );
-   v.reset();
-   ASSERT_EQ( data[ 1 ], 3 );
-}*/
+   EXPECT_EQ( u.getSize(), 0 );
+   EXPECT_EQ( v.getElement( 0 ), 50 );
+
+   if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) {
+      typename ArrayType::ElementType data[ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
+      u.bind( data, 10 );
+      EXPECT_EQ( u.getData(), data );
+      EXPECT_EQ( u.getSize(), 10 );
+      EXPECT_EQ( u.getElement( 1 ), 2 );
+      v.bind( u );
+      EXPECT_EQ( v.getElement( 1 ), 2 );
+      u.reset();
+      v.setElement( 1, 3 );
+      v.reset();
+      EXPECT_EQ( data[ 1 ], 3 );
+   }
+}
 
-#endif  /* GTEST_HAS_TYPED_TEST */
+TYPED_TEST( ArrayTest, swap )
+{
+   using ArrayType = typename TestFixture::ArrayType;
 
-typedef int ElementType;
-typedef Devices::Host Device;
-typedef int IndexType;
+   ArrayType u( 10 ), v( 20 );
+   u.setValue( 0 );
+   v.setValue( 1 );
+   u.swap( v );
+   EXPECT_EQ( u.getSize(), 20 );
+   EXPECT_EQ( v.getSize(), 10 );
+   for( int i = 0; i < 20; i++ )
+      EXPECT_EQ( u.getElement( i ), 1 );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), 0 );
+}
 
-TEST( ArrayTest, testSetGetElement )
+TYPED_TEST( ArrayTest, reset )
 {
-   using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > u;
-   u. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      u. setElement( i, i );
-   for( int i = 0; i < 10; i ++ )
-      ASSERT_EQ( u. getElement( i ), i );
+   using ArrayType = typename TestFixture::ArrayType;
 
-   u.setValue( 0 );
-   if( std::is_same< Device, Devices::Host >::value )
-   {
-      for( int i = 0; i < 10; i ++ )
-         u[ i ] =  i;
+   ArrayType u;
+   u.setSize( 100 );
+   EXPECT_EQ( u.getSize(), 100 );
+   EXPECT_NE( u.getData(), nullptr );
+   u.reset();
+   EXPECT_EQ( u.getSize(), 0 );
+   EXPECT_EQ( u.getData(), nullptr );
+   u.setSize( 100 );
+   EXPECT_EQ( u.getSize(), 100 );
+   EXPECT_NE( u.getData(), nullptr );
+   u.reset();
+   EXPECT_EQ( u.getSize(), 0 );
+   EXPECT_EQ( u.getData(), nullptr );
+}
+
+template< typename Element, typename Index >
+void testArrayElementwiseAccess( Array< Element, Devices::Host, Index >&& u )
+{
+   u.setSize( 10 );
+   for( int i = 0; i < 10; i++ ) {
+      u.setElement( i, i );
+      EXPECT_EQ( u.getData()[ i ], i );
+      EXPECT_EQ( u.getElement( i ), i );
+      EXPECT_EQ( u[ i ], i );
    }
-   if( std::is_same< Device, Devices::Cuda >::value )
-   {
+}
+
 #ifdef HAVE_CUDA
-      Array< ElementType, Device, IndexType >* kernel_u =
-               Devices::Cuda::passToDevice( u );
-      testSetGetElementKernel<<< 1, 16 >>>( kernel_u );
-      Devices::Cuda::freeFromDevice( kernel_u );
-      ASSERT_TRUE( checkCudaDevice );
-#endif
+template< typename ElementType, typename IndexType >
+__global__ void testSetGetElementKernel( Array< ElementType, Devices::Cuda, IndexType >* u )
+{
+   if( threadIdx.x < ( *u ).getSize() )
+      ( *u )[ threadIdx.x ] = threadIdx.x;
+}
+#endif /* HAVE_CUDA */
+
+template< typename Element, typename Index >
+void testArrayElementwiseAccess( Array< Element, Devices::Cuda, Index >&& u )
+{
+#ifdef HAVE_CUDA
+   u.setSize( 10 );
+   using ArrayType = Array< Element, Devices::Cuda, Index >;
+   ArrayType* kernel_u = Devices::Cuda::passToDevice( u );
+   testSetGetElementKernel<<< 1, 16 >>>( kernel_u );
+   Devices::Cuda::freeFromDevice( kernel_u );
+   TNL_CHECK_CUDA_DEVICE;
+   for( int i = 0; i < 10; i++ ) {
+      EXPECT_EQ( u.getElement( i ), i );
    }
-   for( int i = 0; i < 10; i++ )
-      ASSERT_EQ( u.getElement( i ), i );
-};
+#endif
+}
 
-TEST( ArrayTest, testComparisonOperator )
+template< typename Element, typename Index >
+void testArrayElementwiseAccess( Array< Element, Devices::MIC, Index >&& u )
 {
-    using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > u;
-   Array< ElementType, Device, IndexType > v;
-   Array< ElementType, Device, IndexType > w;
-   u. setSize( 10 );
-   v. setSize( 10 );
-   w. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      u. setElement( i, i );
-      v. setElement( i, i );
-      w. setElement( i, 2*1 );
+#ifdef HAVE_MIC
+   // TODO
+#endif
+}
+
+TYPED_TEST( ArrayTest, elementwiseAccess )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   testArrayElementwiseAccess( ArrayType() );
+}
+
+TYPED_TEST( ArrayTest, comparisonOperator )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u( 10 ), v( 10 ), w( 10 );
+   typename ArrayType::HostType u_host( 10 );
+   for( int i = 0; i < 10; i ++ ) {
+      u.setElement( i, i );
+      u_host.setElement( i, i );
+      v.setElement( i, i );
+      w.setElement( i, 2 * i );
    }
-   ASSERT_TRUE( u == v );
-   ASSERT_FALSE( u != v );
-   ASSERT_TRUE( u != w );
-   ASSERT_FALSE( u == w );
-};
+   EXPECT_TRUE( u == u );
+   EXPECT_TRUE( u == v );
+   EXPECT_TRUE( v == u );
+   EXPECT_FALSE( u != v );
+   EXPECT_FALSE( v != u );
+   EXPECT_TRUE( u != w );
+   EXPECT_TRUE( w != u );
+   EXPECT_FALSE( u == w );
+   EXPECT_FALSE( w == u );
+
+   // comparison with different device
+   EXPECT_TRUE( u == u_host );
+   EXPECT_TRUE( u_host == u );
+   EXPECT_TRUE( w != u_host );
+   EXPECT_TRUE( u_host != w );
+
+   v.setSize( 0 );
+   EXPECT_FALSE( u == v );
+   u.setSize( 0 );
+   EXPECT_TRUE( u == v );
+}
 
-TEST( ArrayTest, testAssignmentOperator )
+// TODO: comparison with different device
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+/*
+TYPED_TEST( ArrayTest, comparisonOperatorWithDifferentType )
 {
-   using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > u;
-   Array< ElementType, Device, IndexType > v;
-   u. setSize( 10 );
-   v. setSize( 10 );
+   Array< short, typename ArrayType::DeviceType, short > z( 10 );
+   for( int i = 0; i < 10; i ++ )
+      z.setElement( i, i );
+   EXPECT_TRUE( u == z );
+   EXPECT_FALSE( u != z );
    for( int i = 0; i < 10; i ++ )
-      u. setElement( i, i );
+      z.setElement( i, 2 * i );
+   EXPECT_FALSE( u == z );
+   EXPECT_TRUE( u != z );
+}
+*/
+
+TYPED_TEST( ArrayTest, assignmentOperator )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u( 10 ), v( 10 );
+   typename ArrayType::HostType u_host( 10 );
+   for( int i = 0; i < 10; i++ ) {
+      u.setElement( i, i );
+      u_host.setElement( i, i );
+   }
+
+   v.setValue( 0 );
    v = u;
-   ASSERT_TRUE( u == v );
-   ASSERT_TRUE( v == u );
-   ASSERT_FALSE( u != v );
-   ASSERT_FALSE( v != u );
+   EXPECT_EQ( u, v );
 
+   // assignment from host to device
    v.setValue( 0 );
-   Array< ElementType, Devices::Host, IndexType > w;
-   w.setSize( 10 );
-   w = u;
+   v = u_host;
+   EXPECT_EQ( u, v );
 
-   ASSERT_TRUE( u == w );
-   ASSERT_FALSE( u != w );
+   // assignment from device to host
+   u_host.setValue( 0 );
+   u_host = u;
+   EXPECT_EQ( u_host, u );
+}
+
+// test works only for arithmetic types
+template< typename ArrayType,
+          typename = typename std::enable_if< std::is_arithmetic< typename ArrayType::ElementType >::value >::type >
+void testArrayAssignmentWithDifferentType()
+{
+   ArrayType u( 10 );
+   Array< short, typename ArrayType::DeviceType, short > v( 10 );
+   Array< short, Devices::Host, short > v_host( 10 );
+   typename ArrayType::HostType u_host( 10 );
+   for( int i = 0; i < 10; i++ ) {
+      u.setElement( i, i );
+      u_host.setElement( i, i );
+   }
 
    v.setValue( 0 );
-   v = w;
-   ASSERT_TRUE( v == w );
-   ASSERT_FALSE( v != w );
-};
+   v = u;
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_EQ( v, u );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), i );
 
-TEST( ArrayTest, testGetSize )
-{
-   using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > u;
-   const int maxSize = 10;
-   for( int i = 0; i < maxSize; i ++ )
-      u. setSize( i );
+   // assignment from host to device
+   v.setValue( 0 );
+   v = u_host;
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_EQ( v, u_host );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), i );
 
-   ASSERT_EQ( u. getSize(), maxSize - 1 );
-};
+   // assignment from host to device
+   v_host.setValue( 0 );
+   v_host = u;
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_EQ( v_host, u );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v_host.getElement( i ), i );
+}
 
-TEST( ArrayTest, testReset )
+template< typename ArrayType,
+          typename = typename std::enable_if< ! std::is_arithmetic< typename ArrayType::ElementType >::value >::type,
+          typename = void >
+void testArrayAssignmentWithDifferentType()
 {
-   using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > u;
-   u. setSize( 100 );
-   ASSERT_EQ( u. getSize(), 100 );
-   u. reset();
-   ASSERT_EQ( u. getSize(), 0 );
-   u. setSize( 100 );
-   ASSERT_EQ( u. getSize(), 100 );
-   u. reset();
-   ASSERT_EQ( u. getSize(), 0 );
+}
 
-};
+TYPED_TEST( ArrayTest, assignmentOperatorWithDifferentType )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   testArrayAssignmentWithDifferentType< ArrayType >();
+}
 
-TEST( ArrayTest, testSetSizeAndDestructor )
+TYPED_TEST( ArrayTest, SaveAndLoad )
 {
-   using namespace TNL::Containers;
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u, v;
+   v.setSize( 100 );
    for( int i = 0; i < 100; i ++ )
-   {
-      Array< ElementType, Device, IndexType > u;
-      u. setSize( i );
-   }
+      v.setElement( i, 3.14147 );
+   File file;
+   file.open( "test-file.tnl", IOMode::write );
+   EXPECT_TRUE( v.save( file ) );
+   file.close();
+   file.open( "test-file.tnl", IOMode::read );
+   EXPECT_TRUE( u.load( file ) );
+   EXPECT_EQ( u, v );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 }
 
-TEST( ArrayTest, testSaveAndLoad )
+TYPED_TEST( ArrayTest, boundLoad )
 {
-   using namespace TNL::Containers;
-   Array< ElementType, Device, IndexType > v;
-   v. setSize( 100 );
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u, v, w;
+   v.setSize( 100 );
    for( int i = 0; i < 100; i ++ )
-      v. setElement( i, 3.14147 );
+      v.setElement( i, 3.14147 );
    File file;
-   file. open( "test-file.tnl", tnlWriteMode );
-   v. save( file );
-   file. close();
-   Array< ElementType, Device, IndexType > u;
-   file. open( "test-file.tnl", tnlReadMode );
-   u. load( file );
-   file. close();
-   ASSERT_TRUE( u == v );
+   file.open( "test-file.tnl", IOMode::write );
+   EXPECT_TRUE( v.save( file ) );
+   file.close();
+
+   w.setSize( 100 );
+   u.bind( w );
+   file.open( "test-file.tnl", IOMode::read );
+   EXPECT_TRUE( u.boundLoad( file ) );
+   EXPECT_EQ( u, v );
+   EXPECT_EQ( u.getData(), w.getData() );
+
+   u.setSize( 50 );
+   file.open( "test-file.tnl", IOMode::read );
+   EXPECT_FALSE( u.boundLoad( file ) );
+
+   u.reset();
+   file.open( "test-file.tnl", IOMode::read );
+   EXPECT_TRUE( u.boundLoad( file ) );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 }
 
-TEST( ArrayTest, testUnusualStructures )
+TYPED_TEST( ArrayTest, referenceCountingConstructors )
 {
-   using namespace TNL::Containers;
-   Array< testingClassForArrayTester >u;
-};
+   using ArrayType = typename TestFixture::ArrayType;
+
+   // copies of a dynamic array
+   ArrayType u( 10 );
+   ArrayType v( u );
+   ArrayType w( v );
+   EXPECT_EQ( v.getData(), u.getData() );
+   EXPECT_EQ( w.getData(), u.getData() );
+
+   // copies of a static array
+   if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) {
+      typename ArrayType::ElementType data[ 10 ] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+      ArrayType u( data, 10 );
+      ArrayType v( u );
+      ArrayType w( v );
+      EXPECT_EQ( u.getData(), data );
+      EXPECT_EQ( v.getData(), data );
+      EXPECT_EQ( w.getData(), data );
+   }
+}
 
-#endif /* HAVE_GTEST */
-   
-#ifdef HAVE_CUDA
-template< typename ElementType, typename IndexType >
-__global__ void testSetGetElementKernel( Array< ElementType, Devices::Cuda, IndexType >* u )
+TYPED_TEST( ArrayTest, referenceCountingBind )
 {
-   if( threadIdx.x < ( *u ).getSize() )
-      ( *u )[ threadIdx.x ] = threadIdx.x;
+   using ArrayType = typename TestFixture::ArrayType;
+
+   // copies of a dynamic array
+   ArrayType u( 10 );
+   ArrayType v;
+   v.bind( u );
+   ArrayType w;
+   w.bind( v );
+   EXPECT_EQ( v.getData(), u.getData() );
+   EXPECT_EQ( w.getData(), u.getData() );
+
+   // copies of a static array
+   if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) {
+      typename ArrayType::ElementType data[ 10 ] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+      ArrayType u( data, 10 );
+      ArrayType v;
+      v.bind( u );
+      ArrayType w;
+      w.bind( v );
+      EXPECT_EQ( u.getData(), data );
+      EXPECT_EQ( v.getData(), data );
+      EXPECT_EQ( w.getData(), data );
+   }
 }
-#endif /* HAVE_CUDA */
 
+// TODO: test all __cuda_callable__ methods from a CUDA kernel
 
+#endif // HAVE_GTEST
+   
+
+#include "../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
-
-
diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt
old mode 100755
new mode 100644
index 3f6b1c4c2d8227734baad4de62a3893c15cbce73..3aa747857a93471dfb06375d746689d1dab9b25e
--- a/src/UnitTests/Containers/CMakeLists.txt
+++ b/src/UnitTests/Containers/CMakeLists.txt
@@ -1,67 +1,83 @@
-IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( ArrayOperationsTest${mpiExt}${debugExt} ArrayOperationsTest.h ArrayOperationsTest.cu )
-   SET_TARGET_PROPERTIES( ArrayOperationsTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( ArrayOperationsTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( ArrayOperationsTest${mpiExt}${debugExt} ArrayOperationsTest.h ArrayOperationsTest.cpp )
-   SET_TARGET_PROPERTIES( ArrayOperationsTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( ArrayOperationsTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ENDIF( BUILD_CUDA )
+ADD_EXECUTABLE( ListTest${mpiExt}${debugExt} ListTest.cpp )
+TARGET_COMPILE_OPTIONS( ListTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( ListTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES}
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
 
 IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( ArrayTest${mpiExt}${debugExt} ArrayTest.h ArrayTest.cu )
-   SET_TARGET_PROPERTIES( ArrayTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( ArrayTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( ArrayTest${mpiExt}${debugExt} ArrayTest.h ArrayTest.cpp )
-   SET_TARGET_PROPERTIES( ArrayTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( ArrayTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+   CUDA_ADD_EXECUTABLE( ArrayOperationsTest${mpiExt}${debugExt} ArrayOperationsTest.cu
+                        OPTIONS ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( ArrayOperationsTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+ELSE(  BUILD_CUDA )
+   ADD_EXECUTABLE( ArrayOperationsTest${mpiExt}${debugExt} ArrayOperationsTest.cpp )
+   TARGET_COMPILE_OPTIONS( ArrayOperationsTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( ArrayOperationsTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
 ENDIF( BUILD_CUDA )
 
 IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( MultiArrayTest${mpiExt}${debugExt} MultiArrayTest.h MultiArrayTest.cu )
-   SET_TARGET_PROPERTIES( MultiArrayTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( MultiArrayTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( StaticArrayTest${mpiExt}${debugExt} StaticArrayTest.h StaticArrayTest.cpp )
-   SET_TARGET_PROPERTIES( StaticArrayTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( StaticArrayTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+   CUDA_ADD_EXECUTABLE( ArrayTest${mpiExt}${debugExt} ArrayTest.cu
+                        OPTIONS ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( ArrayTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+ELSE(  BUILD_CUDA )
+   ADD_EXECUTABLE( ArrayTest${mpiExt}${debugExt} ArrayTest.cpp )
+   TARGET_COMPILE_OPTIONS( ArrayTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( ArrayTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
 ENDIF( BUILD_CUDA )
 
-IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( VectorOperationsTest${mpiExt}${debugExt} VectorOperationsTest.h VectorOperationsTest.cu )
-   SET_TARGET_PROPERTIES( VectorOperationsTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( VectorOperationsTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( VectorOperationsTest${mpiExt}${debugExt} VectorOperationsTest.h VectorOperationsTest.cpp )
-   SET_TARGET_PROPERTIES( VectorOperationsTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( VectorOperationsTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ENDIF( BUILD_CUDA )
+ADD_EXECUTABLE( StaticArrayTest${mpiExt}${debugExt} StaticArrayTest.cpp )
+TARGET_COMPILE_OPTIONS( StaticArrayTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( StaticArrayTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES}
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
 
+# NOTE: Vector = Array + VectorOperations, so we test Vector and VectorOperations at the same time
 IF( BUILD_CUDA )
-   CUDA_ADD_EXECUTABLE( StaticVectorTest${mpiExt}${debugExt} StaticVectorTest.h StaticVectorTest.cu )
-   SET_TARGET_PROPERTIES( StaticVectorTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( StaticVectorTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
-ELSE(  BUILD_CUDA )               
-   ADD_EXECUTABLE( StaticVectorTest${mpiExt}${debugExt} StaticVectorTest.h StaticVectorTest.cpp )
-   SET_TARGET_PROPERTIES( StaticVectorTest${mpiExt}${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_TESTS_FLAGS}" )
-   TARGET_LINK_LIBRARIES( StaticVectorTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
-                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+   CUDA_ADD_EXECUTABLE( VectorTest${mpiExt}${debugExt} VectorTest.cu
+                        OPTIONS ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( VectorTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+ELSE(  BUILD_CUDA )
+   ADD_EXECUTABLE( VectorTest${mpiExt}${debugExt} VectorTest.cpp )
+   TARGET_COMPILE_OPTIONS( VectorTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( VectorTest${mpiExt}${debugExt}
+                              ${GTEST_BOTH_LIBRARIES}
+                              tnl${mpiExt}${debugExt}-${tnlVersion} )
 ENDIF( BUILD_CUDA )
 
+ADD_EXECUTABLE( StaticVectorTest${mpiExt}${debugExt} StaticVectorTest.cpp )
+TARGET_COMPILE_OPTIONS( StaticVectorTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+TARGET_LINK_LIBRARIES( StaticVectorTest${mpiExt}${debugExt}
+                           ${GTEST_BOTH_LIBRARIES}
+                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+
+#IF( BUILD_CUDA )
+#   CUDA_ADD_EXECUTABLE( MultiArrayTest${mpiExt}${debugExt} MultiArrayTest.cu
+#                        OPTIONS ${CXX_TESTS_FLAGS} )
+#   TARGET_LINK_LIBRARIES( MultiArrayTest${mpiExt}${debugExt}
+#                              ${GTEST_BOTH_LIBRARIES}
+#                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+#ELSE(  BUILD_CUDA )
+#   ADD_EXECUTABLE( MultiArrayTest${mpiExt}${debugExt} MultiArrayTest.cpp )
+#   TARGET_COMPILE_OPTIONS( MultiArrayTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+#   TARGET_LINK_LIBRARIES( MultiArrayTest${mpiExt}${debugExt}
+#                              ${GTEST_BOTH_LIBRARIES}
+#                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+#ENDIF( BUILD_CUDA )
+
 
+ADD_TEST( ListTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ListTest${mpiExt}${debugExt} )
 ADD_TEST( ArrayOperationsTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ArrayOperationsTest${mpiExt}${debugExt} )
 ADD_TEST( ArrayTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/ArrayTest${mpiExt}${debugExt} )
-ADD_TEST( MultiArrayTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/MultiArrayTest${mpiExt}${debugExt} )
 ADD_TEST( StaticArrayTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/StaticArrayTest${mpiExt}${debugExt} )
-ADD_TEST( VectorOperationsTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/VectorOperationsTest${mpiExt}${debugExt} )
-ADD_TEST( StaticVectorTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${mpiExt}${debugExt} )
\ No newline at end of file
+ADD_TEST( VectorTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/VectorTest${mpiExt}${debugExt} )
+ADD_TEST( StaticVectorTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${mpiExt}${debugExt} )
+#ADD_TEST( MultiArrayTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/MultiArrayTest${mpiExt}${debugExt} )
diff --git a/src/UnitTests/Containers/ListTest.cpp b/src/UnitTests/Containers/ListTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec81c1f0bf8f3d25be8d0daf98e2625cdc65ab69
--- /dev/null
+++ b/src/UnitTests/Containers/ListTest.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+                          ListTest.cpp  -  description
+                             -------------------
+    begin                : Feb 15, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#ifdef HAVE_GTEST 
+#include <gtest/gtest.h>
+
+#include <TNL/Containers/List.h>
+
+using namespace TNL;
+using namespace TNL::Containers;
+
+
+// test fixture for typed tests
+template< typename List >
+class ListTest : public ::testing::Test
+{
+protected:
+   using ListType = List;
+};
+
+// types for which ListTest is instantiated
+using ListTypes = ::testing::Types<
+   List< short  >,
+   List< int    >,
+   List< long   >,
+   List< float  >,
+   List< double >,
+   List< String >
+>;
+
+TYPED_TEST_CASE( ListTest, ListTypes );
+
+
+TYPED_TEST( ListTest, constructor )
+{
+   using ListType = typename TestFixture::ListType;
+
+   ListType list;
+   EXPECT_TRUE( list.isEmpty() );
+   EXPECT_EQ( list.getSize(), 0 );
+
+   list.Append( 0 );
+   EXPECT_EQ( list.getSize(), 1 );
+
+   ListType copy( list );
+   list.Append( 0 );
+   EXPECT_EQ( list.getSize(), 2 );
+   EXPECT_EQ( copy.getSize(), 1 );
+   EXPECT_EQ( copy[ 0 ], list[ 0 ] );
+}
+
+TYPED_TEST( ListTest, operations )
+{
+   using ListType = typename TestFixture::ListType;
+   using ElementType = typename ListType::ElementType;
+
+   ListType a, b;
+
+   a.Append( 0 );
+   a.Append( 1 );
+   a.Prepend( 2 );
+   a.Insert( 3, 1 );
+   EXPECT_EQ( a.getSize(), 4 );
+   EXPECT_EQ( a[ 0 ], (ElementType) 2 );
+   EXPECT_EQ( a[ 1 ], (ElementType) 3 );
+   EXPECT_EQ( a[ 2 ], (ElementType) 0 );
+   EXPECT_EQ( a[ 3 ], (ElementType) 1 );
+
+   b = a;
+   EXPECT_EQ( b.getSize(), 4 );
+   EXPECT_EQ( a, b );
+
+   b.Insert( 4, 4 );
+   EXPECT_NE( a, b );
+   EXPECT_EQ( b[ 4 ], (ElementType) 4 );
+
+   a.AppendList( b );
+   EXPECT_EQ( a.getSize(), 9 );
+   EXPECT_EQ( a[ 0 ], (ElementType) 2 );
+   EXPECT_EQ( a[ 1 ], (ElementType) 3 );
+   EXPECT_EQ( a[ 2 ], (ElementType) 0 );
+   EXPECT_EQ( a[ 3 ], (ElementType) 1 );
+   EXPECT_EQ( a[ 4 ], (ElementType) 2 );
+   EXPECT_EQ( a[ 5 ], (ElementType) 3 );
+   EXPECT_EQ( a[ 6 ], (ElementType) 0 );
+   EXPECT_EQ( a[ 7 ], (ElementType) 1 );
+   EXPECT_EQ( a[ 8 ], (ElementType) 4 );
+
+   a.PrependList( b );
+   EXPECT_EQ( a.getSize(), 14 );
+   EXPECT_EQ( a[ 0 ],  (ElementType) 2 );
+   EXPECT_EQ( a[ 1 ],  (ElementType) 3 );
+   EXPECT_EQ( a[ 2 ],  (ElementType) 0 );
+   EXPECT_EQ( a[ 3 ],  (ElementType) 1 );
+   EXPECT_EQ( a[ 4 ],  (ElementType) 4 );
+   EXPECT_EQ( a[ 5 ],  (ElementType) 2 );
+   EXPECT_EQ( a[ 6 ],  (ElementType) 3 );
+   EXPECT_EQ( a[ 7 ],  (ElementType) 0 );
+   EXPECT_EQ( a[ 8 ],  (ElementType) 1 );
+   EXPECT_EQ( a[ 9 ],  (ElementType) 2 );
+   EXPECT_EQ( a[ 10 ], (ElementType) 3 );
+   EXPECT_EQ( a[ 11 ], (ElementType) 0 );
+   EXPECT_EQ( a[ 12 ], (ElementType) 1 );
+   EXPECT_EQ( a[ 13 ], (ElementType) 4 );
+}
+#endif
+
+
+#include "../GtestMissingError.h"
+int main( int argc, char* argv[] )
+{
+#ifdef HAVE_GTEST
+   ::testing::InitGoogleTest( &argc, argv );
+   return RUN_ALL_TESTS();
+#else
+   throw GtestMissingError();
+#endif
+}
diff --git a/src/UnitTests/Containers/MultiArrayTest.h b/src/UnitTests/Containers/MultiArrayTest.h
index 413ae01ca3b9ab9e701d6273110e2c46b1501339..c1a506c26a2d451de59819c70cc3faf7c09552ab 100644
--- a/src/UnitTests/Containers/MultiArrayTest.h
+++ b/src/UnitTests/Containers/MultiArrayTest.h
@@ -51,13 +51,13 @@ __global__ void testSetGetElementKernel( MultiArray< 3, ElementType, Devices::Cu
 TEST( MultiArrayTest, testConstructorDestructor )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
 }
 
 TEST( MultiArrayTest, testSetSize )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u, v;
+   MultiArray< Dimension, ElementType, Device, IndexType > u, v;
    u. setDimensions( 10 );
    v. setDimensions( 10 );
 }
@@ -105,7 +105,7 @@ IndexType getDiagonalElement( Containers::MultiArray< 3, ElementType, Device, In
 TEST( MultiArrayTest, testSetGetElement )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
    u. setDimensions( 10 );
    if( std::is_same< Device, Devices::Host >::value )
    {
@@ -115,11 +115,11 @@ TEST( MultiArrayTest, testSetGetElement )
    if( std::is_same< Device, Devices::Cuda >::value )
    {
 #ifdef HAVE_CUDA
-      MultiArray< Dimensions, ElementType, Device, IndexType >* kernel_u =
+      MultiArray< Dimension, ElementType, Device, IndexType >* kernel_u =
                Devices::Cuda::passToDevice( u );
       testSetGetElementKernel<<< 1, 16 >>>( kernel_u );
       Devices::Cuda::freeFromDevice( kernel_u );
-      ASSERT_TRUE( checkCudaDevice );
+      ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
 #endif
    }
    for( int i = 0; i < 10; i ++ )
@@ -129,7 +129,7 @@ TEST( MultiArrayTest, testSetGetElement )
 TEST( MultiArrayTest, testComparisonOperator )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u, v, w;
+   MultiArray< Dimension, ElementType, Device, IndexType > u, v, w;
    u.setDimensions( 10 );
    v.setDimensions( 10 );
    w.setDimensions( 10 );
@@ -151,8 +151,8 @@ TEST( MultiArrayTest, testComparisonOperator )
 TEST( MultiArrayTest, testEquivalenceOperator )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
-   MultiArray< Dimensions, ElementType, Device, IndexType > v;
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
+   MultiArray< Dimension, ElementType, Device, IndexType > v;
    u. setDimensions( 10 );
    v. setDimensions( 10 );
    for( int i = 0; i < 10; i ++ )
@@ -165,7 +165,7 @@ TEST( MultiArrayTest, testEquivalenceOperator )
 TEST( MultiArrayTest, testGetSize )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
    const int maxSize = 10;
    for( int i = 1; i < maxSize; i ++ )
       u. setDimensions( i );
@@ -176,7 +176,7 @@ TEST( MultiArrayTest, testGetSize )
 TEST( MultiArrayTest, testReset )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
    u.setDimensions( 100 );
    ASSERT_EQ( u. getDimensions().x(), 100 );
    u.reset();
@@ -193,7 +193,7 @@ TEST( MultiArrayTest, testSetSizeAndDestructor )
    using namespace TNL::Containers;
    for( int i = 1; i < 100; i ++ )
    {
-      MultiArray< Dimensions, ElementType, Device, IndexType > u;
+      MultiArray< Dimension, ElementType, Device, IndexType > u;
       u. setDimensions( i );
    }
 }
@@ -201,20 +201,22 @@ TEST( MultiArrayTest, testSetSizeAndDestructor )
 TEST( MultiArrayTest, testSaveAndLoad )
 {
    using namespace TNL::Containers;
-   MultiArray< Dimensions, ElementType, Device, IndexType > v;
+   MultiArray< Dimension, ElementType, Device, IndexType > v;
    const int size( 10 );
    ASSERT_TRUE( v. setDimensions( size ) );
    for( int i = 0; i < size; i ++ )
       setDiagonalElement( v, i, 3.14147 );
    File file;
-   file. open( "test-file.tnl", tnlWriteMode );
+   file. open( "test-file.tnl", IOMode::write );
    ASSERT_TRUE( v. save( file ) );
    file. close();
-   MultiArray< Dimensions, ElementType, Device, IndexType > u;
-   file. open( "test-file.tnl", tnlReadMode );
+   MultiArray< Dimension, ElementType, Device, IndexType > u;
+   file. open( "test-file.tnl", IOMode::read );
    ASSERT_TRUE( u. load( file ) );
    file. close();
    ASSERT_TRUE( u == v );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 }
 #endif /* HAVE_GTEST */
 
diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp
index afb3017f0909920565046725a8b38a332117bc21..dfe99c5876ccc855d8ab62464f59456490e403e2 100644
--- a/src/UnitTests/Containers/StaticArrayTest.cpp
+++ b/src/UnitTests/Containers/StaticArrayTest.cpp
@@ -8,4 +8,304 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "StaticArrayTest.h"
+#ifdef HAVE_GTEST
+#include <TNL/Containers/StaticArray.h>
+#include <TNL/Containers/Array.h>
+
+#include "gtest/gtest.h"
+
+using namespace TNL;
+using namespace TNL::Containers;
+
+
+// test fixture for typed tests
+template< typename Array >
+class StaticArrayTest : public ::testing::Test
+{
+protected:
+   using ArrayType = Array;
+   using ElementType = typename Array::ElementType;
+};
+
+// types for which ArrayTest is instantiated
+using StaticArrayTypes = ::testing::Types<
+   StaticArray< 1, short >,
+   StaticArray< 2, short >,
+   StaticArray< 3, short >,
+   StaticArray< 4, short >,
+   StaticArray< 5, short >,
+   StaticArray< 1, int >,
+   StaticArray< 2, int >,
+   StaticArray< 3, int >,
+   StaticArray< 4, int >,
+   StaticArray< 5, int >,
+   StaticArray< 1, long >,
+   StaticArray< 2, long >,
+   StaticArray< 3, long >,
+   StaticArray< 4, long >,
+   StaticArray< 5, long >,
+   StaticArray< 1, float >,
+   StaticArray< 2, float >,
+   StaticArray< 3, float >,
+   StaticArray< 4, float >,
+   StaticArray< 5, float >,
+   StaticArray< 1, double >,
+   StaticArray< 2, double >,
+   StaticArray< 3, double >,
+   StaticArray< 4, double >,
+   StaticArray< 5, double >
+>;
+
+TYPED_TEST_CASE( StaticArrayTest, StaticArrayTypes );
+
+TYPED_TEST( StaticArrayTest, constructors )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   using ElementType = typename TestFixture::ElementType;
+   constexpr int Size = ArrayType::size;
+
+   ElementType data[ Size ];
+   for( int i = 0; i < Size; i++ )
+      data[ i ] = i;
+
+   ArrayType u0;
+   EXPECT_TRUE( u0.getData() );
+
+   ArrayType u1( data );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u1[ i ], data[ i ] );
+
+   ArrayType u2( 7 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u2[ i ], 7 );
+
+   ArrayType u3( u1 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u3[ i ], u1[ i ] );
+
+   // initialization with 0 requires special treatment to avoid ambiguity,
+   // see https://stackoverflow.com/q/4610503
+   ArrayType v( 0 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( v[ i ], 0 );
+}
+
+TYPED_TEST( StaticArrayTest, getSize )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u;
+   EXPECT_EQ( u.getSize(), Size );
+}
+
+TYPED_TEST( StaticArrayTest, getData )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u1;
+   EXPECT_TRUE( u1.getData() );
+
+   const ArrayType u2;
+   EXPECT_TRUE( u2.getData() );
+}
+
+template< typename Element >
+void checkCoordinates( StaticArray< 1, Element >& u )
+{
+   EXPECT_EQ( u.x(), 0 );
+   u.x() += 1;
+   EXPECT_EQ( u.x(), 1 );
+}
+
+template< typename Element >
+void checkCoordinates( StaticArray< 2, Element >& u )
+{
+   EXPECT_EQ( u.x(), 0 );
+   EXPECT_EQ( u.y(), 1 );
+   u.x() += 1;
+   u.y() += 1;
+   EXPECT_EQ( u.x(), 1 );
+   EXPECT_EQ( u.y(), 2 );
+}
+
+template< typename Element >
+void checkCoordinates( StaticArray< 3, Element >& u )
+{
+   EXPECT_EQ( u.x(), 0 );
+   EXPECT_EQ( u.y(), 1 );
+   EXPECT_EQ( u.z(), 2 );
+   u.x() += 1;
+   u.y() += 1;
+   u.z() += 1;
+   EXPECT_EQ( u.x(), 1 );
+   EXPECT_EQ( u.y(), 2 );
+   EXPECT_EQ( u.z(), 3 );
+}
+
+template< int _Size, typename Element >
+void checkCoordinates( StaticArray< _Size, Element >& u )
+{
+}
+
+TYPED_TEST( StaticArrayTest, CoordinatesGetter )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u;
+   for( int i = 0; i < Size; i++ )
+      u[ i ] = i;
+
+   checkCoordinates( u );
+}
+
+TYPED_TEST( StaticArrayTest, ComparisonOperator )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u1, u2, u3;
+
+   for( int i = 0; i < Size; i++ ) {
+      u1[ i ] = 1;
+      u2[ i ] = i;
+      u3[ i ] = i;
+   }
+
+   EXPECT_TRUE( u1 == u1 );
+   EXPECT_TRUE( u1 != u2 );
+   EXPECT_TRUE( u2 == u3 );
+
+   // comparison with different type
+   StaticArray< Size, char > u4( 1 );
+   EXPECT_TRUE( u1 == u4 );
+   EXPECT_TRUE( u2 != u4 );
+   EXPECT_TRUE( u3 != u4 );
+
+   for( int i = 0; i < Size; i++ )
+      u4[ i ] = i;
+   EXPECT_TRUE( u1 != u4 );
+   EXPECT_TRUE( u2 == u4 );
+   EXPECT_TRUE( u3 == u4 );
+}
+
+TYPED_TEST( StaticArrayTest, AssignmentOperator )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u1, u2, u3;
+
+   for( int i = 0; i < Size; i++ )
+   {
+      u1[ i ] = 1;
+      u2[ i ] = i;
+   }
+
+   u3 = u1;
+   EXPECT_TRUE( u3 == u1 );
+   EXPECT_TRUE( u3 != u2 );
+
+   u3 = u2;
+   EXPECT_TRUE( u3 == u2 );
+   EXPECT_TRUE( u3 != u1 );
+
+   // assignment from different type
+   StaticArray< Size, char > u4( 127 );
+   u3 = u4;
+   EXPECT_TRUE( u3 == u4 );
+}
+
+TYPED_TEST( StaticArrayTest, setValue )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u;
+   u.setValue( 42 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u[ i ], 42 );
+}
+
+TYPED_TEST( StaticArrayTest, CastToDifferentStaticArray )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+   using OtherArray = StaticArray< Size, char >;
+
+   ArrayType u1( 1 );
+   OtherArray u2( 1 );
+   EXPECT_EQ( (OtherArray) u1, u2 );
+   EXPECT_EQ( u1, (ArrayType) u2 );
+}
+
+TYPED_TEST( StaticArrayTest, SaveAndLoad )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u1( 7 ), u2;
+   File file;
+   file.open( "tnl-static-array-test.tnl", IOMode::write );
+   u1.save( file );
+   file.close();
+   file.open( "tnl-static-array-test.tnl", IOMode::read );
+   u2.load( file );
+   file.close();
+
+   EXPECT_EQ( u1, u2 );
+
+   EXPECT_EQ( std::remove( "tnl-static-array-test.tnl" ), 0 );
+}
+
+TYPED_TEST( StaticArrayTest, sort )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType u;
+   for( int i = 0; i < Size; i++ )
+      u[ i ] = Size - i - 1;
+   u.sort();
+
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u[ i ], i );
+}
+
+TYPED_TEST( StaticArrayTest, streamOperator )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+
+   ArrayType u;
+   std::stringstream testStream;
+   testStream << u;
+}
+
+TYPED_TEST( StaticArrayTest, BindToArray )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   using ElementType = typename TestFixture::ElementType;
+   constexpr int Size = ArrayType::size;
+
+   ArrayType a;
+   for( int i = 0; i < Size; i++ )
+      a[ i ] = i+1;
+
+   Array< ElementType, Devices::Host > sharedArray;
+   sharedArray.bind( a );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( a[ i ], sharedArray[ i ] );
+}
+#endif // HAVE_GTEST
+
+
+#include "../GtestMissingError.h"
+int main( int argc, char* argv[] )
+{
+#ifdef HAVE_GTEST
+   ::testing::InitGoogleTest( &argc, argv );
+   return RUN_ALL_TESTS();
+#else
+   throw GtestMissingError();
+#endif
+}
diff --git a/src/UnitTests/Containers/StaticArrayTest.h b/src/UnitTests/Containers/StaticArrayTest.h
deleted file mode 100644
index b26af6f60673f037c4cea63d3a6d1eddc9b06c42..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/StaticArrayTest.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/***************************************************************************
-                          StaticArrayTester.h  -  description
-                             -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/Containers/StaticArray.h>
-#include <TNL/Containers/Array.h>
-
-#ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-using namespace TNL;
-using namespace TNL::Containers;
-
-class testingClassForStaticArrayTester
-{
-   public:
-
-      static String getType()
-      {
-         return String( "testingClassForStaticArrayTester" );
-      };
-};
-
-String getType( const testingClassForStaticArrayTester& c )
-{
-   return String( "testingClassForStaticArrayTester" );
-};
-
-#ifdef HAVE_GTEST
-
-typedef int ElementType;
-const int Size( 16 );
-
-
-TEST( StaticArrayTest, testConstructors )
-{
-   ElementType data[ Size ];
-   for( int i = 0; i < Size; i++ )
-      data[ i ] = i;
-
-   StaticArray< Size, ElementType > u1( data );
-   for( int i = 0; i < Size; i++ )
-      ASSERT_EQ( u1[ i ], data[ i ] );
-
-   StaticArray< Size, ElementType > u2( 7 );
-   for( int i = 0; i < Size; i++ )
-      ASSERT_EQ( u2[ i ], 7 );
-
-   StaticArray< Size, ElementType > u3( u1 );
-   for( int i = 0; i < Size; i++ )
-      ASSERT_EQ( u3[ i ], u1[ i ] );
-}
-
-template< typename Element >
-void checkCoordinates( const StaticArray< 1, Element >& u )
-{
-   ASSERT_EQ( u.x(), 0 );
-}
-
-template< typename Element >
-void checkCoordinates( const StaticArray< 2, Element >& u )
-{
-   ASSERT_EQ( u.x(), 0 );
-   ASSERT_EQ( u.y(), 1 );
-}
-
-template< typename Element >
-void checkCoordinates( const StaticArray< 3, Element >& u )
-{
-   ASSERT_EQ( u.x(), 0 );
-   ASSERT_EQ( u.y(), 1 );
-   ASSERT_EQ( u.z(), 2 );
-}
-
-template< int _Size, typename Element >
-void checkCoordinates( const StaticArray< _Size, Element >& u )
-{
-}
-
-TEST( StaticArrayTest, testCoordinatesGetter )
-{
-   StaticArray< Size, ElementType > u;
-   for( int i = 0; i < Size; i++ )
-      u[ i ] = i;
-
-   checkCoordinates( u );
-}
-
-TEST( StaticArrayTest, testComparisonOperator )
-{
-   StaticArray< Size, ElementType > u1, u2, u3;
-
-   for( int i = 0; i < Size; i++ )
-   {
-      u1[ i ] = 1;
-      u2[ i ] = i;
-      u3[ i ] = i;
-   }
-
-   ASSERT_TRUE( u1 == u1 );
-   ASSERT_TRUE( u1 != u2 );
-   ASSERT_TRUE( u2 == u3 );
-}
-
-TEST( StaticArrayTest, testAssignmentOperator )
-{
-   StaticArray< Size, ElementType > u1, u2, u3;
-
-   for( int i = 0; i < Size; i++ )
-   {
-      u1[ i ] = 1;
-      u2[ i ] = i;
-   }
-
-   u3 = u1;
-   ASSERT_TRUE( u3 == u1 );
-   ASSERT_TRUE( u3 != u2 );
-
-   u3 = u2;
-   ASSERT_TRUE( u3 == u2 );
-   ASSERT_TRUE( u3 != u1 );
-}
-
-TEST( StaticArrayTest, testLoadAndSave )
-{
-   StaticArray< Size, ElementType > u1( 7 ), u2( 0 );
-   File file;
-   file.open( "tnl-static-array-test.tnl", tnlWriteMode );
-   u1.save( file );
-   file.close();
-   file.open( "tnl-static-array-test.tnl", tnlReadMode );
-   u2.load( file );
-   file.close();
-
-   ASSERT_EQ( u1, u2 );
-}
-
-TEST( StaticArrayTest, testSort )
-{
-   StaticArray< Size, ElementType > u;
-   for( int i = 0; i < Size; i++ )
-      u[ i ] = Size - i - 1;
-   u.sort();
-
-   for( int i = 0; i < Size; i++ )
-      ASSERT_EQ( u[ i ], i );
-}
-
-TEST( StaticArrayTest, testStreamOperator )
-{
-   StaticArray< Size, ElementType > u;
-   std::stringstream testStream;
-   testStream << u;
-}
-
-TEST( StaticArrayTest, testBindToArray )
-{
-   StaticArray< Size, ElementType > a;
-   for( int i = 0; i < Size; i++ )
-      a[ i ] = i+1;
-
-   Array< ElementType, Devices::Host > sharedArray;
-   sharedArray.bind( a );
-   for( int i = 0; i < Size; i++ )
-      ASSERT_EQ( a[ i ], sharedArray[ i ] );
-
-}
-#endif /* HAVE_GTEST */
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_GTEST
-   ::testing::InitGoogleTest( &argc, argv );
-   return RUN_ALL_TESTS();
-#else
-   return EXIT_FAILURE;
-#endif
-}
-
diff --git a/src/UnitTests/Containers/StaticVectorTest.cpp b/src/UnitTests/Containers/StaticVectorTest.cpp
index 3505faf2c9ea1cc85566d7f1347f1fb3a8ec2ff5..e34db3f33833dc3254e13bc0b2c650a2613abd22 100644
--- a/src/UnitTests/Containers/StaticVectorTest.cpp
+++ b/src/UnitTests/Containers/StaticVectorTest.cpp
@@ -8,4 +8,196 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "StaticVectorTest.h"
+#ifdef HAVE_GTEST
+#include <TNL/Containers/StaticVector.h>
+
+#include "gtest/gtest.h"
+
+using namespace TNL;
+using namespace TNL::Containers;
+
+// test fixture for typed tests
+template< typename Vector >
+class StaticVectorTest : public ::testing::Test
+{
+protected:
+   using VectorType = Vector;
+   using RealType = typename VectorType::RealType;
+};
+
+// types for which VectorTest is instantiated
+using StaticVectorTypes = ::testing::Types<
+   StaticVector< 1, short >,
+   StaticVector< 1, int >,
+   StaticVector< 1, long >,
+   StaticVector< 1, float >,
+   StaticVector< 1, double >,
+   StaticVector< 2, short >,
+   StaticVector< 2, int >,
+   StaticVector< 2, long >,
+   StaticVector< 2, float >,
+   StaticVector< 2, double >,
+   StaticVector< 3, short >,
+   StaticVector< 3, int >,
+   StaticVector< 3, long >,
+   StaticVector< 3, float >,
+   StaticVector< 3, double >,
+   StaticVector< 4, short >,
+   StaticVector< 4, int >,
+   StaticVector< 4, long >,
+   StaticVector< 4, float >,
+   StaticVector< 4, double >,
+   StaticVector< 5, short >,
+   StaticVector< 5, int >,
+   StaticVector< 5, long >,
+   StaticVector< 5, float >,
+   StaticVector< 5, double >
+>;
+
+TYPED_TEST_CASE( StaticVectorTest, StaticVectorTypes );
+
+
+TYPED_TEST( StaticVectorTest, constructors )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using RealType = typename TestFixture::RealType;
+   constexpr int Size = VectorType::size;
+
+   RealType data[ Size ];
+   for( int i = 0; i < Size; i++ )
+      data[ i ] = i;
+
+   VectorType u0;
+   EXPECT_TRUE( u0.getData() );
+
+   VectorType u1( data );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u1[ i ], data[ i ] );
+
+   VectorType u2( 7 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u2[ i ], 7 );
+
+   VectorType u3( u1 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( u3[ i ], u1[ i ] );
+
+   // initialization with 0 requires special treatment to avoid ambiguity,
+   // see https://stackoverflow.com/q/4610503
+   VectorType v( 0 );
+   for( int i = 0; i < Size; i++ )
+      EXPECT_EQ( v[ i ], 0 );
+}
+
+TYPED_TEST( StaticVectorTest, operators )
+{
+   using VectorType = typename TestFixture::VectorType;
+   constexpr int size = VectorType::size;
+
+   VectorType u1( 1 ), u2( 2 ), u3( 3 );
+
+   u1 += u2;
+   EXPECT_EQ( u1[ 0 ], 3 );
+   EXPECT_EQ( u1[ size - 1 ], 3 );
+
+   u1 -= u2;
+   EXPECT_EQ( u1[ 0 ], 1 );
+   EXPECT_EQ( u1[ size - 1 ], 1 );
+
+   u1 *= 2;
+   EXPECT_EQ( u1[ 0 ], 2 );
+   EXPECT_EQ( u1[ size - 1 ], 2 );
+
+   u3 = u1 + u2;
+   EXPECT_EQ( u3[ 0 ], 4 );
+   EXPECT_EQ( u3[ size - 1 ], 4 );
+
+   u3 = u1 - u2;
+   EXPECT_EQ( u3[ 0 ], 0 );
+   EXPECT_EQ( u3[ size - 1 ], 0 );
+
+   u3 = 2 * u1;
+   EXPECT_EQ( u3[ 0 ], 4 );
+   EXPECT_EQ( u3[ size - 1 ], 4 );
+
+   EXPECT_EQ( u1 * u2, 4 * size );
+}
+
+TYPED_TEST( StaticVectorTest, comparisons )
+{
+   using VectorType = typename TestFixture::VectorType;
+   constexpr int size = VectorType::size;
+
+   VectorType u1( 1 ), u2( 2 ), u3( 3 ), u4;
+   for( int i = 0; i < size; i++ )
+      u4[ i ] = i;
+
+   EXPECT_TRUE( u1 < u3 );
+   EXPECT_TRUE( u1 <= u3 );
+   EXPECT_TRUE( u1 < u2 );
+   EXPECT_TRUE( u1 <= u2 );
+   EXPECT_TRUE( u3 > u1 );
+   EXPECT_TRUE( u3 >= u1 );
+   EXPECT_TRUE( u2 > u1 );
+   EXPECT_TRUE( u2 >= u1 );
+
+   if( size > 2 ) {
+      EXPECT_FALSE( u1 < u4 );
+      EXPECT_FALSE( u1 <= u4 );
+      EXPECT_FALSE( u1 > u4 );
+      EXPECT_FALSE( u1 >= u4 );
+   }
+}
+
+TYPED_TEST( StaticVectorTest, cast )
+{
+   using VectorType = typename TestFixture::VectorType;
+   constexpr int size = VectorType::size;
+
+   VectorType u( 1 );
+   EXPECT_EQ( (StaticVector< size, double >) u, u );
+}
+
+TYPED_TEST( StaticVectorTest, abs )
+{
+   using VectorType = typename TestFixture::VectorType;
+   constexpr int size = VectorType::size;
+
+   VectorType u;
+   for( int i = 0; i < size; i++ )
+      u[ i ] = i;
+
+   // TODO: implement unary minus operator
+   VectorType v = - 1 * u;
+   EXPECT_EQ( v.abs(), u );
+}
+
+TYPED_TEST( StaticVectorTest, lpNorm )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using RealType = typename TestFixture::RealType;
+   constexpr int size = VectorType::size;
+   const RealType epsilon = std::numeric_limits< RealType >::epsilon();
+
+   VectorType v( 1 );
+
+   const RealType expectedL1norm = size;
+   const RealType expectedL2norm = std::sqrt( size );
+   const RealType expectedL3norm = std::cbrt( size );
+   EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm );
+   EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm );
+   EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon );
+}
+#endif
+
+
+#include "../GtestMissingError.h"
+int main( int argc, char* argv[] )
+{
+#ifdef HAVE_GTEST
+   ::testing::InitGoogleTest( &argc, argv );
+   return RUN_ALL_TESTS();
+#else
+   throw GtestMissingError();
+#endif
+}
diff --git a/src/UnitTests/Containers/StaticVectorTest.h b/src/UnitTests/Containers/StaticVectorTest.h
deleted file mode 100644
index 038ea0f4c7959a36e6cb3bcb8852267ca321e013..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/StaticVectorTest.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
-                          StaticVectorTester.h  -  description
-                             -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/Containers/StaticVector.h>
-
-#ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-using namespace TNL;
-
-#ifdef HAVE_GTEST
-
-const int Size( 16 );
-typedef double RealType;
-
-TEST( StaticVectorTest, testOperators )
-{
-   Containers::StaticVector< Size, RealType > u1( 1.0 ), u2( 2.0 ), u3( 3.0 );
-
-   u1 += u2;
-   ASSERT_TRUE( u1[ 0 ] == 3.0 );
-   ASSERT_TRUE( u1[ Size - 1 ] == 3.0 );
-
-   u1 -= u2;
-   ASSERT_TRUE( u1[ 0 ] == 1.0 );
-   ASSERT_TRUE( u1[ Size - 1 ] == 1.0 );
-
-   u1 *= 2.0;
-   ASSERT_TRUE( u1[ 0 ] == 2.0 );
-   ASSERT_TRUE( u1[ Size - 1 ] == 2.0 );
-
-   u3 = u1 + u2;
-   ASSERT_TRUE( u3[ 0 ] == 4.0 );
-   ASSERT_TRUE( u3[ Size - 1 ] == 4.0 );
-
-   u3 = u1 - u2;
-   ASSERT_TRUE( u3[ 0 ] == 0.0 );
-   ASSERT_TRUE( u3[ Size - 1 ] == 0.0 );
-
-   u3 = u1 * 2.0;
-   ASSERT_TRUE( u3[ 0 ] == 4.0 );
-   ASSERT_TRUE( u3[ Size - 1 ] == 4.0 );
-
-   ASSERT_TRUE( u1 * u2 == 4.0 * Size );
-
-   ASSERT_TRUE( u1 < u3 );
-   ASSERT_TRUE( u1 <= u3 );
-   ASSERT_TRUE( u1 <= u2 );
-   ASSERT_TRUE( u3 > u1 );
-   ASSERT_TRUE( u3 >= u1 );
-   ASSERT_TRUE( u2 >= u1 );
-}
-
-#endif
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_GTEST
-   ::testing::InitGoogleTest( &argc, argv );
-   return RUN_ALL_TESTS();
-#else
-   return EXIT_FAILURE;
-#endif
-}
diff --git a/src/UnitTests/Containers/VectorOperationsTest.cu b/src/UnitTests/Containers/VectorOperationsTest.cu
deleted file mode 100644
index 61d3b0357b9fb1c3e5b8decfe74ed6cae9446c25..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/VectorOperationsTest.cu
+++ /dev/null
@@ -1,11 +0,0 @@
-/***************************************************************************
-                          Devices::CudaVectorOperationsTest.cu  -  description
-                             -------------------
-    begin                : Mar 31, 2013
-    copyright            : (C) 2013 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
- 
-#include "VectorOperationsTest.h"
diff --git a/src/UnitTests/Containers/VectorOperationsTest.h b/src/UnitTests/Containers/VectorOperationsTest.h
deleted file mode 100644
index 6f7d7d46ce3d89b77309c34343af12e60af5b90f..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/VectorOperationsTest.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/***************************************************************************
-                          VectorOperationsTester.h  -  description
-                             -------------------
-    begin                : Mar 30, 2013
-    copyright            : (C) 2013 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorOperations.h>
-
-using namespace TNL;
-using namespace TNL::Containers;
-
-#ifdef HAVE_GTEST
-
-typedef double Real;
-typedef Devices::Host Device;
-typedef int Index;
-
-template< typename Vector >
-void setLinearSequence( Vector& deviceVector )
-{
-   Containers::Vector< typename Vector :: RealType, Devices::Host > a;
-   a. setSize( deviceVector. getSize() );
-   for( int i = 0; i < a. getSize(); i ++ )
-      a. getData()[ i ] = i;
-
-   ArrayOperations< typename Vector::DeviceType,
-                       Devices::Host >::
-   template copyMemory< typename Vector::RealType,
-                        typename Vector::RealType,
-                        typename Vector::IndexType >
-                      ( deviceVector.getData(),
-                        a.getData(),
-                        a.getSize() );
-}
-
-
-template< typename Vector >
-void setOnesSequence( Vector& deviceVector )
-{
-   Containers::Vector< typename Vector :: RealType, Devices::Host > a;
-   a. setSize( deviceVector. getSize() );
-   for( int i = 0; i < a. getSize(); i ++ )
-      a. getData()[ i ] = 1;
-
-   ArrayOperations< typename Vector::DeviceType,
-                       Devices::Host >::
-   template copyMemory< typename Vector::RealType,
-                        typename Vector::RealType,
-                        typename Vector::IndexType >
-                      ( deviceVector.getData(),
-                        a.getData(),
-                        a.getSize() );
-}
-
-
-template< typename Vector >
-void setNegativeLinearSequence( Vector& deviceVector )
-{
-   Containers::Vector< typename Vector :: RealType, Devices::Host > a;
-   a. setSize( deviceVector. getSize() );
-   for( int i = 0; i < a. getSize(); i ++ )
-      a. getData()[ i ] = -i;
-
-   ArrayOperations< typename Vector::DeviceType,
-                       Devices::Host >::
-   template copyMemory< typename Vector::RealType,
-                        typename Vector::RealType,
-                        typename Vector::IndexType >
-                      ( deviceVector.getData(),
-                        a.getData(),
-                        a.getSize() );
-}
-
-template< typename Vector >
-void setOscilatingSequence( Vector& deviceVector,
-                            typename Vector::RealType v )
-{
-   Containers::Vector< typename Vector::RealType, Devices::Host > a;
-   a.setSize( deviceVector. getSize() );
-   a[ 0 ] = v;
-   for( int i = 1; i < a. getSize(); i ++ )
-      a.getData()[ i ] = a.getData()[ i-1 ] * -1;
-
-   ArrayOperations< typename Vector::DeviceType,
-                       Devices::Host >::
-   template copyMemory< typename Vector::RealType,
-                        typename Vector::RealType,
-                        typename Vector::IndexType >
-                      ( deviceVector.getData(),
-                        a.getData(),
-                        a.getSize() );
-}
-
-
-
-TEST( VectorOperationsTest, getVectorMaxTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setLinearSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorMax( v ) == size - 1 );
-}
-
-TEST( VectorOperationsTest, getVectorMinTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setLinearSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorMin( v ) == 0 );
-}
-
-TEST( VectorOperationsTest, getVectorAbsMaxTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setNegativeLinearSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorAbsMax( v ) == size - 1 );
-}
-
-TEST( VectorOperationsTest, getVectorAbsMinTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setNegativeLinearSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorAbsMin( v ) == 0 );
-}
-
-TEST( VectorOperationsTest, getVectorLpNormTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorLpNorm( v, 2.0 ) == ::sqrt( size ) );
-}
-
-TEST( VectorOperationsTest, getVectorSumTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > v;
-   v. setSize( size );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorSum( v ) == size );
-
-   setLinearSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorSum( v ) == ( ( Real ) size ) * ( ( Real ) size - 1 ) / 2 );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceMaxTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   setLinearSequence( u );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceMax( u, v ) == size - 2 );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceMinTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   setLinearSequence( u );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceMin( u, v ) == -1 );
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceMin( v, u ) == -123454 );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceAbsMaxTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   setNegativeLinearSequence( u );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceAbsMax( u, v ) == size );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceAbsMinTest )
-{
-   const int size( 123456 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   setLinearSequence( u );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceAbsMin( u, v ) == 0 );
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceAbsMin( v, u ) == 0 );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceLpNormTest )
-{
-   const int size( 1024 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   u. setValue( 3.0 );
-   v. setValue( 1.0 );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceLpNorm( u, v, 1.0 ) == 2.0 * size );
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceLpNorm( u, v, 2.0 ) == ::sqrt( 4.0 * size ) );
-}
-
-TEST( VectorOperationsTest, getVectorDifferenceSumTest )
-{
-   const int size( 1024 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   u. setValue( 3.0 );
-   v. setValue( 1.0 );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getVectorDifferenceSum( u, v ) == 2.0 * size );
-}
-
-TEST( VectorOperationsTest, vectorScalarMultiplicationTest )
-{
-   const int size( 1025 );
-   Containers::Vector< Real, Device > u;
-   u. setSize( size );
-   setLinearSequence( u );
-
-   Containers::VectorOperations< Device >::vectorScalarMultiplication( u, 3.0 );
-
-   for( int i = 0; i < size; i++ )
-      ASSERT_TRUE( u.getElement( i ) == 3.0 * i );
-}
-
-TEST( VectorOperationsTest, getVectorScalarProductTest )
-{
-   const int size( 1025 );
-   Containers::Vector< Real, Device > u, v;
-   u. setSize( size );
-   v. setSize( size );
-   setOscilatingSequence( u, 1.0 );
-   setOnesSequence( v );
-
-   ASSERT_TRUE( Containers::VectorOperations< Device > :: getScalarProduct( u, v ) == 1.0 );
-}
-
-TEST( VectorOperationsTest, addVectorTest )
-{
-   const int size( 10000 );
-   Containers::Vector< Real, Device > x, y;
-   x.setSize( size );
-   y.setSize( size );
-   setLinearSequence( x );
-   setOnesSequence( y );
-   Containers::VectorOperations< Device >::addVector( y, x, 3.0 );
-
-   for( int i = 0; i < size; i ++ )
-      ASSERT_TRUE( y.getElement( i ) == 1.0 + 3.0 * i );
-};
-
-TEST( VectorOperationsTest, prefixSumTest )
-{
-   const int size( 10000 );
-   Containers::Vector< Real, Device > v;
-   v.setSize( size );
-
-   setOnesSequence( v );
-   v.computePrefixSum();
-   for( int i = 0; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) == i + 1 );
-
-   v.setValue( 0 );
-   v.computePrefixSum();
-   for( int i = 0; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) == 0 );
-
-   setLinearSequence( v );
-   v.computePrefixSum();
-   for( int i = 1; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) - v.getElement( i - 1 ) == i );
-
-};
-
-TEST( VectorOperationsTest, exclusivePrefixSumTest )
-{
-   const int size( 10000 );
-   Containers::Vector< Real, Device > v;
-   v.setSize( size );
-
-   setOnesSequence( v );
-   v.computeExclusivePrefixSum();
-   for( int i = 0; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) == i );
-
-   v.setValue( 0 );
-   v.computeExclusivePrefixSum();
-   for( int i = 0; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) == 0 );
-
-   setLinearSequence( v );
-   v.computeExclusivePrefixSum();
-   for( int i = 1; i < size; i++ )
-      ASSERT_TRUE( v.getElement( i ) - v.getElement( i - 1 ) == i - 1 );
-
-};
-
-#endif /* HAVE_GTEST */
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_GTEST
-   ::testing::InitGoogleTest( &argc, argv );
-   return RUN_ALL_TESTS();
-#else
-   return EXIT_FAILURE;
-#endif
-}
diff --git a/src/UnitTests/Containers/VectorTest.cu b/src/UnitTests/Containers/VectorTest.cu
index e36b670972b5cf89558a9a2e13a3db817631ea31..f173d4a5ee71749ebf318fba56430101125c0bd4 100644
--- a/src/UnitTests/Containers/VectorTest.cu
+++ b/src/UnitTests/Containers/VectorTest.cu
@@ -8,4 +8,4 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "tnlVectorTest.h"
+#include "VectorTest.h"
diff --git a/src/UnitTests/Containers/VectorTest.h b/src/UnitTests/Containers/VectorTest.h
index 56966b64a2620c3fa4c7d6aef21a805aa7b0b857..2f3832fcda5439e617dfe9cea27bd8a11dadd6cb 100644
--- a/src/UnitTests/Containers/VectorTest.h
+++ b/src/UnitTests/Containers/VectorTest.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          VectorTester.h  -  description
+                          VectorTest.h  -  description
                              -------------------
     begin                : Oct 25, 2010
     copyright            : (C) 2010 by Tomas Oberhuber
@@ -8,206 +8,526 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
+// NOTE: Vector = Array + VectorOperations, so we test Vector and VectorOperations at the same time
+
 #pragma once
 
+#ifdef HAVE_GTEST
+#include <limits>
+
 #include <TNL/Containers/Vector.h>
 #include <TNL/File.h>
 #include <TNL/Math.h>
 
+#include "gtest/gtest.h"
+
 using namespace TNL;
+using namespace TNL::Containers;
+using namespace TNL::Containers::Algorithms;
+
+// should be small enough to have fast tests, but larger than minGPUReductionDataSize
+// and large enough to require multiple CUDA blocks for reduction
+constexpr int VECTOR_TEST_SIZE = 5000;
 
-#ifdef HAVE_GTEST
 
-TEST( VectorTest, testMax )
+template< typename Vector >
+void setLinearSequence( Vector& deviceVector )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v. setElement( i, i );
-   ASSERT_TRUE( v. max() == 9 );
-};
+   typename Vector::HostType a;
+   a.setLike( deviceVector );
+   for( int i = 0; i < a.getSize(); i++ )
+      a[ i ] = i;
+   deviceVector = a;
+}
 
-TEST( VectorTest, testMin )
+template< typename Vector >
+void setConstantSequence( Vector& deviceVector,
+                          typename Vector::RealType v )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v. setElement( i, i );
-   ASSERT_TRUE( v. min() == 0 );
-};
+   deviceVector.setValue( v );
+}
 
-TEST( VectorTest, testAbsMax )
+template< typename Vector >
+void setNegativeLinearSequence( Vector& deviceVector )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement( i, -i );
-   ASSERT_TRUE( v. absMax() == 9 );
-};
+   typename Vector::HostType a;
+   a.setLike( deviceVector );
+   for( int i = 0; i < a.getSize(); i++ )
+      a[ i ] = -i;
+   deviceVector = a;
+}
 
-TEST( VectorTest, testAbsMin )
+template< typename Vector >
+void setOscilatingSequence( Vector& deviceVector,
+                            typename Vector::RealType v )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement( i,  -i );
-   ASSERT_TRUE( v. absMin() == 0 );
-};
+   typename Vector::HostType a;
+   a.setLike( deviceVector );
+   a[ 0 ] = v;
+   for( int i = 1; i < a.getSize(); i++ )
+      a[ i ] = a[ i-1 ] * -1;
+   deviceVector = a;
+}
+
+
+// TODO: test everything with OpenMP with different number of threads
 
-TEST( VectorTest, testLpNorm )
+// test fixture for typed tests
+template< typename Vector >
+class VectorTest : public ::testing::Test
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement(  i, -2 );
-   ASSERT_TRUE( isSmall( v.lpNorm( 1 ) - 20.0 ) );
-   ASSERT_TRUE( isSmall( v.lpNorm( 2 ) - ::sqrt( 40.0 ) ) );
-   ASSERT_TRUE( isSmall( v.lpNorm( 3 ) - ::pow( 80.0, 1.0/3.0 ) ) );
+protected:
+   using VectorType = Vector;
+   using VectorOperations = Algorithms::VectorOperations< typename VectorType::DeviceType >;
 };
 
-TEST( VectorTest, testSum )
+// types for which VectorTest is instantiated
+using VectorTypes = ::testing::Types<
+   Vector< int,    Devices::Host, short >,
+   Vector< long,   Devices::Host, short >,
+   Vector< float,  Devices::Host, short >,
+   Vector< double, Devices::Host, short >,
+   Vector< int,    Devices::Host, int >,
+   Vector< long,   Devices::Host, int >,
+   Vector< float,  Devices::Host, int >,
+   Vector< double, Devices::Host, int >,
+   Vector< int,    Devices::Host, long >,
+   Vector< long,   Devices::Host, long >,
+   Vector< float,  Devices::Host, long >,
+   Vector< double, Devices::Host, long >
+#ifdef HAVE_CUDA
+   ,
+   Vector< int,    Devices::Cuda, short >,
+   Vector< long,   Devices::Cuda, short >,
+   Vector< float,  Devices::Cuda, short >,
+   Vector< double, Devices::Cuda, short >,
+   Vector< int,    Devices::Cuda, int >,
+   Vector< long,   Devices::Cuda, int >,
+   Vector< float,  Devices::Cuda, int >,
+   Vector< double, Devices::Cuda, int >,
+   Vector< int,    Devices::Cuda, long >,
+   Vector< long,   Devices::Cuda, long >,
+   Vector< float,  Devices::Cuda, long >,
+   Vector< double, Devices::Cuda, long >
+#endif
+#ifdef HAVE_MIC
+   ,
+   Vector< int,    Devices::MIC, short >,
+   Vector< long,   Devices::MIC, short >,
+   Vector< float,  Devices::MIC, short >,
+   Vector< double, Devices::MIC, short >,
+   Vector< int,    Devices::MIC, int >,
+   Vector< long,   Devices::MIC, int >,
+   Vector< float,  Devices::MIC, int >,
+   Vector< double, Devices::MIC, int >,
+   Vector< int,    Devices::MIC, long >,
+   Vector< long,   Devices::MIC, long >,
+   Vector< float,  Devices::MIC, long >,
+   Vector< double, Devices::MIC, long >
+#endif
+>;
+
+TYPED_TEST_CASE( VectorTest, VectorTypes );
+
+
+TYPED_TEST( VectorTest, max )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement( i, -2 );
-   ASSERT_TRUE( v. sum() == -20.0 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement( i,  2 );
-   ASSERT_TRUE( v. sum() == 20.0 );
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
 
-};
+   VectorType v;
+   v.setSize( size );
+   setLinearSequence( v );
+
+   EXPECT_EQ( v.max(), size - 1 );
+   EXPECT_EQ( VectorOperations::getVectorMax( v ), size - 1 );
+}
 
-TEST( VectorTest, testDifferenceMax )
+TYPED_TEST( VectorTest, min )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i,  i );
-      v2.setElement( i, -i );
-   }
-   ASSERT_TRUE( v1. differenceMax( v2 ) == 18.0 );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+   setLinearSequence( v );
+
+   EXPECT_EQ( v.min(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorMin( v ), 0 );
+}
 
-TEST( VectorTest, testDifferenceMin )
+TYPED_TEST( VectorTest, absMax )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, i );
-      v2.setElement( i, -i );
-   }
-   ASSERT_TRUE( v1. differenceMin( v2 ) == 0.0 );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+   setNegativeLinearSequence( v );
 
-TEST( VectorTest, testDifferenceAbsMax )
+   EXPECT_EQ( v.absMax(), size - 1 );
+   EXPECT_EQ( VectorOperations::getVectorAbsMax( v ), size - 1 );
+}
+
+TYPED_TEST( VectorTest, absMin )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, -i );
-      v2.setElement( i, i );
-   }
-   ASSERT_TRUE( v1. differenceAbsMax( v2 ) == 18.0 );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
 
-TEST( VectorTest, testDifferenceAbsMin )
+   VectorType v;
+   v.setSize( size );
+   setNegativeLinearSequence( v );
+
+   EXPECT_EQ( v.absMin(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorAbsMin( v ), 0 );
+}
+
+TYPED_TEST( VectorTest, lpNorm )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, -i );
-      v2.setElement( i, i );
-   }
-   ASSERT_TRUE( v1. differenceAbsMin( v2 ) == 0.0 );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using RealType = typename VectorType::RealType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
+
+   VectorType v;
+   v.setSize( size );
+   setConstantSequence( v, 1 );
+
+   const RealType expectedL1norm = size;
+   const RealType expectedL2norm = std::sqrt( size );
+   const RealType expectedL3norm = std::cbrt( size );
+   EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm );
+   EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm );
+   EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( VectorOperations::getVectorLpNorm( v, 3.0 ), expectedL3norm, epsilon );
+}
 
-TEST( VectorTest, testDifferenceLpNorm )
+TYPED_TEST( VectorTest, sum )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, -1 );
-      v2.setElement( i, 1 );
-   }
-   ASSERT_TRUE( isSmall( v1.differenceLpNorm( v2, 1.0 ) - 20.0 ) );
-   ASSERT_TRUE( isSmall( v1.differenceLpNorm( v2, 2.0 ) - ::sqrt( 40.0 ) ) );
-   ASSERT_TRUE( isSmall( v1.differenceLpNorm( v2, 3.0 ) - ::pow( 80.0, 1.0/3.0 ) ) );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   // this test expect an even size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+
+   setConstantSequence( v, 1 );
+   EXPECT_EQ( v.sum(), size );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), size );
 
-TEST( VectorTest, testDifferenceSum )
+   setLinearSequence( v );
+   EXPECT_EQ( v.sum(), 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0.5 * size * ( size - 1 ) );
+
+   setNegativeLinearSequence( v );
+   EXPECT_EQ( v.sum(), - 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), - 0.5 * size * ( size - 1 ) );
+
+   setOscilatingSequence( v, 1.0 );
+   EXPECT_EQ( v.sum(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0 );
+}
+
+TYPED_TEST( VectorTest, differenceMax )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, -1 );
-      v2.setElement( i, 1 );
-   }
-   ASSERT_TRUE( v1. differenceSum( v2 ) == -20.0 );
-};
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
 
-TEST( VectorTest, testScalarMultiplication )
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   setLinearSequence( u );
+   setConstantSequence( v, size / 2 );
+
+   EXPECT_EQ( u.differenceMax( v ), size - 1 - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMax( u, v ), size - 1 - size / 2 );
+}
+
+TYPED_TEST( VectorTest, differenceMin )
 {
-   Containers::Vector< RealType, Device, IndexType > v;
-   v. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-      v.setElement( i, i );
-   v. scalarMultiplication( 5.0 );
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
 
-   for( int i = 0; i < 10; i ++ )
-      ASSERT_TRUE( v. getElement( i ) == 5 * i );
-};
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   setLinearSequence( u );
+   setConstantSequence( v, size / 2 );
+
+   EXPECT_EQ( u.differenceMin( v ), - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( u, v ), - size / 2 );
+   EXPECT_EQ( v.differenceMin( u ), size / 2 - size + 1 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( v, u ), size / 2 - size + 1 );
+}
+
+TYPED_TEST( VectorTest, differenceAbsMax )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   // this test expects an odd size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
+
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   setNegativeLinearSequence( u );
+   setConstantSequence( v, - size / 2 );
 
-TEST( VectorTest, testScalarProduct )
-{
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   v1.setElement( 0, -1 );
-   v2.setElement( 0, 1 );
-   for( int i = 1; i < 10; i ++ )
-   {
-      v1.setElement( i, v1.getElement( i - 1 ) * -1 );
-      v2.setElement( i, v2.getElement( i - 1 ) );
+   EXPECT_EQ( u.differenceAbsMax( v ), size - 1 - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMax( u, v ), size - 1 - size / 2 );
+}
+
+TYPED_TEST( VectorTest, differenceAbsMin )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   setNegativeLinearSequence( u );
+   setConstantSequence( v, - size / 2 );
+
+   EXPECT_EQ( u.differenceAbsMin( v ), 0 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( u, v ), 0 );
+   EXPECT_EQ( v.differenceAbsMin( u ), 0 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( v, u ), 0 );
+}
+
+TYPED_TEST( VectorTest, differenceLpNorm )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using RealType = typename VectorType::RealType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
+
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   u.setValue( 3.0 );
+   v.setValue( 1.0 );
+
+   const RealType expectedL1norm = 2.0 * size;
+   const RealType expectedL2norm = std::sqrt( 4.0 * size );
+   const RealType expectedL3norm = std::cbrt( 8.0 * size );
+   EXPECT_EQ( u.differenceLpNorm( v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( u.differenceLpNorm( v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( u.differenceLpNorm( v, 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( VectorOperations::getVectorDifferenceLpNorm( u, v, 3.0 ), expectedL3norm, epsilon );
+}
+
+TYPED_TEST( VectorTest, differenceSum )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   // this test expect an even size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
+
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   v.setValue( 1.0 );
+
+   setConstantSequence( u, 2 );
+   EXPECT_EQ( u.differenceSum( v ), size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), size );
+
+   setLinearSequence( u );
+   EXPECT_EQ( u.differenceSum( v ), 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), 0.5 * size * ( size - 1 ) - size );
+
+   setNegativeLinearSequence( u );
+   EXPECT_EQ( u.differenceSum( v ), - 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - 0.5 * size * ( size - 1 ) - size );
+
+   setOscilatingSequence( u, 1.0 );
+   EXPECT_EQ( u.differenceSum( v ), - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - size );
+}
+
+TYPED_TEST( VectorTest, scalarMultiplication )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType u;
+   u.setSize( size );
+
+   typename VectorType::HostType expected;
+   expected.setSize( size );
+   for( int i = 0; i < size; i++ )
+      expected[ i ] = 2.0 * i;
+
+   setLinearSequence( u );
+   VectorOperations::vectorScalarMultiplication( u, 2.0 );
+   EXPECT_EQ( u, expected );
+
+   setLinearSequence( u );
+   u.scalarMultiplication( 2.0 );
+   EXPECT_EQ( u, expected );
+
+   setLinearSequence( u );
+   u *= 2.0;
+   EXPECT_EQ( u, expected );
+}
+
+TYPED_TEST( VectorTest, scalarProduct )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   // this test expects an odd size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
+
+   VectorType u, v;
+   u.setSize( size );
+   v.setSize( size );
+   setOscilatingSequence( u, 1.0 );
+   setConstantSequence( v, 1 );
+
+   EXPECT_EQ( u.scalarProduct( v ), 1.0 );
+   EXPECT_EQ( VectorOperations::getScalarProduct( u, v ), 1.0 );
+}
+
+TYPED_TEST( VectorTest, addVector )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType x, y;
+   x.setSize( size );
+   y.setSize( size );
+
+   typename VectorType::HostType expected1, expected2;
+   expected1.setSize( size );
+   expected2.setSize( size );
+   for( int i = 0; i < size; i++ ) {
+      expected1[ i ] = 2.0 + 3.0 * i;
+      expected2[ i ] = 1.0 + 3.0 * i;
    }
-   ASSERT_TRUE( v1. scalarProduct( v2 ) == 0.0 );
-};
 
-TEST( VectorTest, addVectorTest )
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   VectorOperations::addVector( x, y, 3.0, 2.0 );
+   EXPECT_EQ( x, expected1 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   x.addVector( y, 3.0, 1.0 );
+   EXPECT_EQ( x, expected2 );
+}
+
+TYPED_TEST( VectorTest, addVectors )
 {
-   Containers::Vector< RealType, Device, IndexType > v1, v2;
-   v1. setSize( 10 );
-   v2. setSize( 10 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      v1.setElement( i, i );
-      v2.setElement( i, 2.0 * i );
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType x, y, z;
+   x.setSize( size );
+   y.setSize( size );
+   z.setSize( size );
+
+   typename VectorType::HostType expected1, expected2;
+   expected1.setSize( size );
+   expected2.setSize( size );
+   for( int i = 0; i < size; i++ ) {
+      expected1[ i ] = 1.0 + 3.0 * i + 2.0;
+      expected2[ i ] = 2.0 + 3.0 * i + 2.0;
    }
-   v1. addVector( v2, 2.0 );
-   for( int i = 0; i < 10; i ++ )
-      ASSERT_TRUE( v1. getElement( i ) == 5.0 * i );
-};
 
-#endif /* HAVE_GTEST */
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   setConstantSequence( z, 2 );
+   VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 );
+   EXPECT_EQ( x, expected1 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   setConstantSequence( z, 2 );
+   x.addVectors( y, 3.0, z, 1.0, 2.0 );
+   EXPECT_EQ( x, expected2 );
+}
+
+// TODO: fix the CUDA implementations
+TYPED_TEST( VectorTest, prefixSum )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+
+   setConstantSequence( v, 1 );
+   v.computePrefixSum();
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ), i + 1 );
+
+   v.setValue( 0 );
+   v.computePrefixSum();
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ), 0 );
+
+   setLinearSequence( v );
+   v.computePrefixSum();
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
+}
+
+// TODO: fix the CUDA implementations
+TYPED_TEST( VectorTest, exclusivePrefixSum )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+
+   setConstantSequence( v, 1 );
+   v.computeExclusivePrefixSum();
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ), i );
+
+   v.setValue( 0 );
+   v.computeExclusivePrefixSum();
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ), 0 );
+
+   setLinearSequence( v );
+   v.computeExclusivePrefixSum();
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
+}
+
+// TODO: test prefix sum with custom begin and end parameters
+
+#endif // HAVE_GTEST
+
 
+#include "../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h
index 82b8b286c6ba576b95569b0ab7fc5d2ec4e1cda8..b1385f4122924185cfa898b569238e0118aa84af 100644
--- a/src/UnitTests/FileTest.h
+++ b/src/UnitTests/FileTest.h
@@ -1,8 +1,8 @@
 /***************************************************************************
-                          tnlFileTester.h  -  description
+                          FileTest.h  -  description
                              -------------------
     begin                : Oct 24, 2010
-    copyright            : (C) 2010 by Tomas Oberhuber
+    copyright            : (C) 2010 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
@@ -11,60 +11,43 @@
 #include <TNL/File.h>
 
 #ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-#ifdef HAVE_CUDA
-#include <cuda.h>
-#endif
+#include <gtest/gtest.h>
 
 using namespace TNL;
 
-#ifdef HAVE_GTEST
+TEST( FileTest, CloseEmpty )
+{
+   File file;
+   ASSERT_TRUE( file.close() );
+}
+
 TEST( FileTest, WriteAndRead )
 {
    File file;
-   if( ! file. open( String( "test-file.tnl" ), tnlWriteMode ) )
-   {
-      std::cerr << "Unable to create file test-file.tnl for the testing." << std::endl;
-      return;
-   }
+   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) );
+
    int intData( 5 );
-#ifdef HAVE_NOT_CXX11
-   file. write< int, Devices::Host >( &intData );
-#else
-   file. write( &intData );
-#endif
    double doubleData[ 3 ] = { 1.0, 2.0, 3.0 };
-#ifdef HAVE_NOT_CXX11
-   file. write< double, Devices::Host >( doubleData, 3 );
-#else
-   file. write( doubleData, 3 );
-#endif
-   if( ! file. close() )
-   {
-      std::cerr << "Unable to close the file test-file.tnl" << std::endl;
-      return;
-   }
-
-   if( ! file. open( String( "test-file.tnl" ), tnlReadMode ) )
-   {
-      std::cerr << "Unable to open the file test-file.tnl for the testing." << std::endl;
-      return;
-   }
+   const double constDoubleData = 3.14;
+   ASSERT_TRUE( file.write( &intData ) );
+   ASSERT_TRUE( file.write( doubleData, 3 ) );
+   ASSERT_TRUE( file.write( &constDoubleData ) );
+   ASSERT_TRUE( file.close() );
+
+   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) );
    int newIntData;
    double newDoubleData[ 3 ];
-#ifdef HAVE_NOT_CXX11
-   file. read< int, Devices::Host >( &newIntData );
-   file. read< double, Devices::Host >( newDoubleData, 3 );
-#else
-   file. read( &newIntData, 1 );
-   file. read( newDoubleData, 3 );
-#endif
+   double newConstDoubleData;
+   ASSERT_TRUE( file.read( &newIntData, 1 ) );
+   ASSERT_TRUE( file.read( newDoubleData, 3 ) );
+   ASSERT_TRUE( file.read( &newConstDoubleData, 1 ) );
 
-   ASSERT_EQ( newIntData, intData );
+   EXPECT_EQ( newIntData, intData );
    for( int i = 0; i < 3; i ++ )
-      ASSERT_EQ( newDoubleData[ i ], doubleData[ i ] );
+      EXPECT_EQ( newDoubleData[ i ], doubleData[ i ] );
+   EXPECT_EQ( newConstDoubleData, constDoubleData );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 };
 
 #ifdef HAVE_CUDA
@@ -72,11 +55,14 @@ TEST( FileTest, WriteAndReadCUDA )
 {
    int intData( 5 );
    float floatData[ 3 ] = { 1.0, 2.0, 3.0 };
+   const double constDoubleData = 3.14;
 
    int* cudaIntData;
    float* cudaFloatData;
+   const double* cudaConstDoubleData;
    cudaMalloc( ( void** ) &cudaIntData, sizeof( int ) );
    cudaMalloc( ( void** ) &cudaFloatData, 3 * sizeof( float ) );
+   cudaMalloc( ( void** ) &cudaConstDoubleData, sizeof( double ) );
    cudaMemcpy( cudaIntData,
                &intData,
                sizeof( int ),
@@ -85,34 +71,38 @@ TEST( FileTest, WriteAndReadCUDA )
                floatData,
                3 * sizeof( float ),
                cudaMemcpyHostToDevice );
+   cudaMemcpy( (void*) cudaConstDoubleData,
+               &constDoubleData,
+               sizeof( double ),
+               cudaMemcpyHostToDevice );
+
    File file;
-   if( ! file. open( String( "test-file.tnl" ), tnlWriteMode ) )
-   {
-      std::cerr << "Unable to create file test-file.tnl for the testing." << std::endl;
-      return;
-   }
-
-   file. write< int, Devices::Cuda >( cudaIntData );
-   file. write< float, Devices::Cuda, int >( cudaFloatData, 3 );
-   if( ! file. close() )
-   {
-      std::cerr << "Unable to close the file test-file.tnl" << std::endl;
-      return;
-   }
-
-   if( ! file. open( String( "test-file.tnl" ), tnlReadMode ) )
-   {
-      std::cerr << "Unable to open the file test-file.tnl for the testing." << std::endl;
-      return;
-   }
+   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) );
+
+   bool status = file.write< int, Devices::Cuda >( cudaIntData );
+   ASSERT_TRUE( status );
+   status = file.write< float, Devices::Cuda, int >( cudaFloatData, 3 );
+   ASSERT_TRUE( status );
+   status = file.write< const double, Devices::Cuda >( cudaConstDoubleData );
+   ASSERT_TRUE( status );
+   ASSERT_TRUE( file.close() );
+
+   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) );
    int newIntData;
    float newFloatData[ 3 ];
+   double newDoubleData;
    int* newCudaIntData;
    float* newCudaFloatData;
+   double* newCudaDoubleData;
    cudaMalloc( ( void** ) &newCudaIntData, sizeof( int ) );
    cudaMalloc( ( void** ) &newCudaFloatData, 3 * sizeof( float ) );
-   file. read< int, Devices::Cuda >( newCudaIntData, 1 );
-   file. read< float, Devices::Cuda, int >( newCudaFloatData, 3 );
+   cudaMalloc( ( void** ) &newCudaDoubleData, sizeof( double ) );
+   status = file.read< int, Devices::Cuda >( newCudaIntData, 1 );
+   ASSERT_TRUE( status );
+   status = file.read< float, Devices::Cuda, int >( newCudaFloatData, 3 );
+   ASSERT_TRUE( status );
+   status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 );
+   ASSERT_TRUE( status );
    cudaMemcpy( &newIntData,
                newCudaIntData,
                sizeof( int ),
@@ -121,20 +111,28 @@ TEST( FileTest, WriteAndReadCUDA )
                newCudaFloatData,
                3 * sizeof( float ),
                cudaMemcpyDeviceToHost );
+   cudaMemcpy( &newDoubleData,
+               newCudaDoubleData,
+               sizeof( double ),
+               cudaMemcpyDeviceToHost );
 
-   ASSERT_EQ( newIntData, intData );
+   EXPECT_EQ( newIntData, intData );
    for( int i = 0; i < 3; i ++ )
-      ASSERT_EQ( newFloatData[ i ], floatData[ i ] );
+      EXPECT_EQ( newFloatData[ i ], floatData[ i ] );
+   EXPECT_EQ( newDoubleData, constDoubleData );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 };
 #endif
 #endif
 
+#include "GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
diff --git a/src/UnitTests/GtestMissingError.h b/src/UnitTests/GtestMissingError.h
new file mode 100644
index 0000000000000000000000000000000000000000..b308a16c8bb02d6afa38f097c48a9242c0512e08
--- /dev/null
+++ b/src/UnitTests/GtestMissingError.h
@@ -0,0 +1,21 @@
+/***************************************************************************
+                          GtestMissingError.h  -  description
+                             -------------------
+    begin                : Jul 2, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <stdexcept>
+
+struct GtestMissingError
+   : public std::runtime_error
+{
+   GtestMissingError()
+   : std::runtime_error( "The GTest library is needed to run the tests." )
+   {}
+};
diff --git a/src/UnitTests/ListTest.cpp b/src/UnitTests/ListTest.cpp
deleted file mode 100644
index d14883f82f0f187000fe9ad17e9a9a01f361c761..0000000000000000000000000000000000000000
--- a/src/UnitTests/ListTest.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/***************************************************************************
-                          tnlListTest.cpp  -  description
-                             -------------------
-    begin                : Feb 15, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-#include <TNL/List.h>
-
-using namespace TNL;
-
-#ifdef HAVE_GTEST 
-#endif
-
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_GTEST
-   ::testing::InitGoogleTest( &argc, argv );
-   return RUN_ALL_TESTS();
-#else
-   return EXIT_FAILURE;
-#endif
-}
-
-
diff --git a/src/UnitTests/Matrices/CMakeLists.txt b/src/UnitTests/Matrices/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7d1a78b2bb0699f5adb68af4c6eda8d5b9791dbf
--- /dev/null
+++ b/src/UnitTests/Matrices/CMakeLists.txt
@@ -0,0 +1,13 @@
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( SparseMatrixCopyTest${mpiExt}${debugExt} SparseMatrixCopyTest.h SparseMatrixCopyTest.cu OPTIONS ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( SparseMatrixCopyTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
+                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+ELSE(  BUILD_CUDA )
+   ADD_EXECUTABLE( SparseMatrixCopyTest${mpiExt}${debugExt} SparseMatrixCopyTest.h SparseMatrixCopyTest.cpp )
+   TARGET_COMPILE_OPTIONS( SparseMatrixCopyTest${mpiExt}${debugExt} PRIVATE ${CXX_TESTS_FLAGS} )
+   TARGET_LINK_LIBRARIES( SparseMatrixCopyTest${mpiExt}${debugExt} ${GTEST_BOTH_LIBRARIES}
+                                                           tnl${mpiExt}${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+ADD_TEST( SparseMatrixCopyTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixCopyTest${mpiExt}${debugExt} )
diff --git a/src/UnitTests/Containers/VectorOperationsTest.cpp b/src/UnitTests/Matrices/SparseMatrixCopyTest.cpp
similarity index 60%
rename from src/UnitTests/Containers/VectorOperationsTest.cpp
rename to src/UnitTests/Matrices/SparseMatrixCopyTest.cpp
index b5a1b57f466d5d3ee768ab2247fa8989bc294266..30b8f64ecfdbf228856d272a71d3de08980f3987 100644
--- a/src/UnitTests/Containers/VectorOperationsTest.cpp
+++ b/src/UnitTests/Matrices/SparseMatrixCopyTest.cpp
@@ -1,12 +1,11 @@
 /***************************************************************************
-                          VectorOperationsTest.cpp  -  description
+                          SparseMatrixCopyTest.cpp  -  description
                              -------------------
-    begin                : Jul 15, 2013
-    copyright            : (C) 2013 by Tomas Oberhuber
+    begin                : Jun 25, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "VectorOperationsTest.h"
-
+#include "SparseMatrixCopyTest.h"
diff --git a/src/UnitTests/Matrices/SparseMatrixCopyTest.cu b/src/UnitTests/Matrices/SparseMatrixCopyTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..431fe481c2db1d5b18cfa849e882c0ed836463c1
--- /dev/null
+++ b/src/UnitTests/Matrices/SparseMatrixCopyTest.cu
@@ -0,0 +1,11 @@
+/***************************************************************************
+                          SparseMatrixCopyTest.cu  -  description
+                             -------------------
+    begin                : Jun 25, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#include "SparseMatrixCopyTest.h"
diff --git a/src/UnitTests/Matrices/SparseMatrixCopyTest.h b/src/UnitTests/Matrices/SparseMatrixCopyTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a11a8b4442527b371603b8f5d43b70b8e4ff558d
--- /dev/null
+++ b/src/UnitTests/Matrices/SparseMatrixCopyTest.h
@@ -0,0 +1,281 @@
+/***************************************************************************
+                          SparseMatrixCopyTest.h -  description
+                             -------------------
+    begin                : Jun 25, 2017
+    copyright            : (C) 2017 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#include <TNL/Matrices/CSR.h>
+#include <TNL/Matrices/Ellpack.h>
+#include <TNL/Matrices/SlicedEllpack.h>
+
+using CSR_host = TNL::Matrices::CSR< int, TNL::Devices::Host, int >;
+using CSR_cuda = TNL::Matrices::CSR< int, TNL::Devices::Cuda, int >;
+using E_host = TNL::Matrices::Ellpack< int, TNL::Devices::Host, int >;
+using E_cuda = TNL::Matrices::Ellpack< int, TNL::Devices::Cuda, int >;
+using SE_host = TNL::Matrices::SlicedEllpack< int, TNL::Devices::Host, int, 2 >;
+using SE_cuda = TNL::Matrices::SlicedEllpack< int, TNL::Devices::Cuda, int, 2 >;
+
+#ifdef HAVE_GTEST 
+#include <gtest/gtest.h>
+
+/*
+ * Sets up the following 7x6 sparse matrix:
+ *
+ *    / 1  2             \
+ *    | 3  4  5          |
+ *    |    6  7  8       |
+ *    |       9 10 11    |
+ *    |         12 13 14 |
+ *    |            15 16 |
+ *    \               17 /
+ */
+template< typename Matrix >
+void setupMatrix( Matrix& m )
+{
+   const int rows = 7;
+   const int cols = 6;
+   m.reset();
+   m.setDimensions( rows, cols );
+   typename Matrix::CompressedRowLengthsVector rowLengths;
+   rowLengths.setSize( rows );
+   rowLengths.setValue( 3 );
+   rowLengths.setElement( 0 , 4 );
+   rowLengths.setElement( 1,  4 );
+   m.setCompressedRowLengths( rowLengths );
+
+   int value = 1;
+   for( int i = 0; i < rows; i++ )
+      for( int j = 0; j < 3; j++ )
+         if( i + j - 1 >= 0 && i + j - 1 < cols )
+            m.setElement( i, i + j - 1, value++ );
+}
+
+template< typename Matrix >
+void checkMatrix( Matrix& m )
+{
+   ASSERT_EQ( m.getRows(), 7 );
+   ASSERT_EQ( m.getColumns(), 6 );
+
+   EXPECT_EQ( m.getElement( 0, 0 ),  1 );
+   EXPECT_EQ( m.getElement( 0, 1 ),  2 );
+   EXPECT_EQ( m.getElement( 0, 2 ),  0 );
+   EXPECT_EQ( m.getElement( 0, 3 ),  0 );
+   EXPECT_EQ( m.getElement( 0, 4 ),  0 );
+   EXPECT_EQ( m.getElement( 0, 5 ),  0 );
+
+   EXPECT_EQ( m.getElement( 1, 0 ),  3 );
+   EXPECT_EQ( m.getElement( 1, 1 ),  4 );
+   EXPECT_EQ( m.getElement( 1, 2 ),  5 );
+   EXPECT_EQ( m.getElement( 1, 3 ),  0 );
+   EXPECT_EQ( m.getElement( 1, 4 ),  0 );
+   EXPECT_EQ( m.getElement( 1, 5 ),  0 );
+
+   EXPECT_EQ( m.getElement( 2, 0 ),  0 );
+   EXPECT_EQ( m.getElement( 2, 1 ),  6 );
+   EXPECT_EQ( m.getElement( 2, 2 ),  7 );
+   EXPECT_EQ( m.getElement( 2, 3 ),  8 );
+   EXPECT_EQ( m.getElement( 2, 4 ),  0 );
+   EXPECT_EQ( m.getElement( 2, 5 ),  0 );
+
+   EXPECT_EQ( m.getElement( 3, 0 ),  0 );
+   EXPECT_EQ( m.getElement( 3, 1 ),  0 );
+   EXPECT_EQ( m.getElement( 3, 2 ),  9 );
+   EXPECT_EQ( m.getElement( 3, 3 ), 10 );
+   EXPECT_EQ( m.getElement( 3, 4 ), 11 );
+   EXPECT_EQ( m.getElement( 3, 5 ),  0 );
+
+   EXPECT_EQ( m.getElement( 4, 0 ),  0 );
+   EXPECT_EQ( m.getElement( 4, 1 ),  0 );
+   EXPECT_EQ( m.getElement( 4, 2 ),  0 );
+   EXPECT_EQ( m.getElement( 4, 3 ), 12 );
+   EXPECT_EQ( m.getElement( 4, 4 ), 13 );
+   EXPECT_EQ( m.getElement( 4, 5 ), 14 );
+
+   EXPECT_EQ( m.getElement( 5, 0 ),  0 );
+   EXPECT_EQ( m.getElement( 5, 1 ),  0 );
+   EXPECT_EQ( m.getElement( 5, 2 ),  0 );
+   EXPECT_EQ( m.getElement( 5, 3 ),  0 );
+   EXPECT_EQ( m.getElement( 5, 4 ), 15 );
+   EXPECT_EQ( m.getElement( 5, 5 ), 16 );
+
+   EXPECT_EQ( m.getElement( 6, 0 ),  0 );
+   EXPECT_EQ( m.getElement( 6, 1 ),  0 );
+   EXPECT_EQ( m.getElement( 6, 2 ),  0 );
+   EXPECT_EQ( m.getElement( 6, 3 ),  0 );
+   EXPECT_EQ( m.getElement( 6, 4 ),  0 );
+   EXPECT_EQ( m.getElement( 6, 5 ), 17 );
+}
+
+template< typename Matrix1, typename Matrix2 >
+void testCopyAssignment()
+{
+   Matrix1 m1;
+   setupMatrix( m1 );
+   checkMatrix( m1 );
+
+   Matrix2 m2;
+   m2 = m1;
+   checkMatrix( m2 );
+}
+
+template< typename Matrix1, typename Matrix2 >
+void testConversion()
+{
+   Matrix1 m1;
+   setupMatrix( m1 );
+   checkMatrix( m1 );
+
+   Matrix2 m2;
+   TNL::Matrices::copySparseMatrix( m2, m1 );
+   checkMatrix( m2 );
+}
+
+
+TEST( SparseMatrixCopyTest, CSR_HostToHost )
+{
+   testCopyAssignment< CSR_host, CSR_host >();
+}
+
+#ifdef HAVE_CUDA
+TEST( SparseMatrixCopyTest, CSR_HostToCuda )
+{
+   testCopyAssignment< CSR_host, CSR_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, CSR_CudaToHost )
+{
+   testCopyAssignment< CSR_cuda, CSR_host >();
+}
+
+TEST( SparseMatrixCopyTest, CSR_CudaToCuda )
+{
+   testCopyAssignment< CSR_cuda, CSR_cuda >();
+}
+#endif
+
+
+TEST( SparseMatrixCopyTest, Ellpack_HostToHost )
+{
+   testCopyAssignment< E_host, E_host >();
+}
+
+#ifdef HAVE_CUDA
+TEST( SparseMatrixCopyTest, Ellpack_HostToCuda )
+{
+   testCopyAssignment< E_host, E_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_CudaToHost )
+{
+   testCopyAssignment< E_cuda, E_host >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_CudaToCuda )
+{
+   testCopyAssignment< E_cuda, E_cuda >();
+}
+#endif
+
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_HostToHost )
+{
+   testCopyAssignment< SE_host, SE_host >();
+}
+
+#ifdef HAVE_CUDA
+TEST( SparseMatrixCopyTest, SlicedEllpack_HostToCuda )
+{
+   testCopyAssignment< SE_host, SE_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_CudaToHost )
+{
+   testCopyAssignment< SE_cuda, SE_host >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_CudaToCuda )
+{
+   testCopyAssignment< SE_cuda, SE_cuda >();
+}
+#endif
+
+
+// test conversion between formats
+TEST( SparseMatrixCopyTest, CSR_to_Ellpack_host )
+{
+   testConversion< CSR_host, E_host >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_to_CSR_host )
+{
+   testConversion< E_host, CSR_host >();
+}
+
+TEST( SparseMatrixCopyTest, CSR_to_SlicedEllpack_host )
+{
+   testConversion< CSR_host, SE_host >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_to_CSR_host )
+{
+   testConversion< SE_host, CSR_host >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_to_SlicedEllpack_host )
+{
+   testConversion< E_host, SE_host >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_to_Ellpack_host )
+{
+   testConversion< SE_host, E_host >();
+}
+
+#ifdef HAVE_CUDA
+TEST( SparseMatrixCopyTest, CSR_to_Ellpack_cuda )
+{
+   testConversion< CSR_cuda, E_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_to_CSR_cuda )
+{
+   testConversion< E_cuda, CSR_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, CSR_to_SlicedEllpack_cuda )
+{
+   testConversion< CSR_cuda, SE_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_to_CSR_cuda )
+{
+   testConversion< SE_cuda, CSR_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, Ellpack_to_SlicedEllpack_cuda )
+{
+   testConversion< E_cuda, SE_cuda >();
+}
+
+TEST( SparseMatrixCopyTest, SlicedEllpack_to_Ellpack_cuda )
+{
+   testConversion< SE_cuda, E_cuda >();
+}
+#endif
+
+#endif
+
+#include "../GtestMissingError.h"
+int main( int argc, char* argv[] )
+{
+#ifdef HAVE_GTEST
+   ::testing::InitGoogleTest( &argc, argv );
+   return RUN_ALL_TESTS();
+#else
+   throw GtestMissingError();
+#endif
+}
diff --git a/src/UnitTests/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp
index 557d1239ba2aceca88c65f3f4f253641ebd4a5d8..7b9badd8f9d14ce3a9af45249efe9360b07b2e69 100644
--- a/src/UnitTests/ObjectTest.cpp
+++ b/src/UnitTests/ObjectTest.cpp
@@ -11,9 +11,10 @@
 #include <TNL/Devices/Host.h>
 #include <TNL/Object.h>
 #include <TNL/File.h>
+#include <TNL/Containers/Array.h>
 
 #ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 #endif
 
 using namespace TNL;
@@ -23,23 +24,95 @@ TEST( ObjectTest, SaveAndLoadTest )
 {
    Object testObject;
    File file;
-   file.open( "test-file.tnl", tnlWriteMode );
+   file.open( "test-file.tnl", IOMode::write );
    ASSERT_TRUE( testObject.save( file ) );
    file.close();
-   file.open( "test-file.tnl", tnlReadMode );
+   file.open( "test-file.tnl", IOMode::read );
    ASSERT_TRUE( testObject.load( file ) );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
+}
+
+TEST( ObjectTest, parseObjectTypeTest )
+{
+   Containers::List< String > parsed;
+   Containers::List< String > expected;
+
+   // plain type
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "int", parsed ) );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   // type with space
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "short int", parsed ) );
+   expected.Append( "short int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "unsigned short int", parsed ) );
+   expected.Append( "unsigned short int" );
+   EXPECT_EQ( parsed, expected );
+
+   // composed type
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "Containers::Vector< double, Devices::Host, int >", parsed ) );
+   expected.Append( "Containers::Vector" );
+   expected.Append( "double" );
+   expected.Append( "Devices::Host" );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "Containers::Vector< Containers::List< String >, Devices::Host, int >", parsed ) );
+   expected.Append( "Containers::Vector" );
+   expected.Append( "Containers::List< String >" );
+   expected.Append( "Devices::Host" );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   // spaces in the template parameter
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< short int >", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "short int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< B< short int >, C >", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "B< short int >" );
+   expected.Append( "C" );
+   EXPECT_EQ( parsed, expected );
+
+   // spaces at different places in the template parameter
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< b , c <E>  ,d>", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "b" );
+   expected.Append( "c <E>" );
+   expected.Append( "d" );
+   EXPECT_EQ( parsed, expected );
 }
 #endif
 
 
+#include "GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
-
-
diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp
index 9b76b0f6d450f2c1f71882a844443d15f270faf4..6651455589ceeea3681930e1efb621259381fb46 100644
--- a/src/UnitTests/StringTest.cpp
+++ b/src/UnitTests/StringTest.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnlStringTest.cpp  -  description
+                          StringTest.cpp  -  description
                              -------------------
     begin                : Jul 22, 2013
     copyright            : (C) 2013 by Tomas Oberhuber
@@ -9,11 +9,12 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 #endif
 
 #include <TNL/String.h>
 #include <TNL/File.h>
+#include <TNL/Containers/List.h>
 
 using namespace TNL;
 
@@ -21,7 +22,7 @@ using namespace TNL;
 TEST( StringTest, BasicConstructor )
 {
    String str;
-   ASSERT_EQ( strcmp( str. getString(), "" ), 0 );
+   EXPECT_EQ( strcmp( str.getString(), "" ), 0 );
 }
 
 TEST( StringTest, ConstructorWithChar )
@@ -31,10 +32,10 @@ TEST( StringTest, ConstructorWithChar )
    String str3( "string3xxx", 0, 3 );
    String str4( "xxxstring4xxx", 3, 3 );
 
-   ASSERT_EQ( strcmp( str1. getString(), "string1" ), 0 );
-   ASSERT_EQ( strcmp( str2. getString(), "string2" ), 0 );
-   ASSERT_EQ( strcmp( str3. getString(), "string3" ), 0 );
-   ASSERT_EQ( strcmp( str4. getString(), "string4" ), 0 );
+   EXPECT_EQ( strcmp( str1.getString(), "string1" ), 0 );
+   EXPECT_EQ( strcmp( str2.getString(), "string2" ), 0 );
+   EXPECT_EQ( strcmp( str3.getString(), "string3" ), 0 );
+   EXPECT_EQ( strcmp( str4.getString(), "string4" ), 0 );
 }
 
 TEST( StringTest, CopyConstructor )
@@ -44,92 +45,255 @@ TEST( StringTest, CopyConstructor )
    String string2( string );
    String emptyString2( emptyString );
 
-   ASSERT_EQ( strcmp( string2. getString(), "string1" ), 0 );
-   ASSERT_EQ( strcmp( emptyString2. getString(), "" ), 0 );
+   EXPECT_EQ( strcmp( string2.getString(), "string1" ), 0 );
+   EXPECT_EQ( strcmp( emptyString2.getString(), "" ), 0 );
 }
 
 TEST( StringTest, ConstructorWithNumber )
 {
    String string1( 10 );
    String string2( -5 );
+   String string3( true );
+   String string4( false );
 
-   ASSERT_EQ( strcmp( string1. getString(), "10" ), 0 );
-   ASSERT_EQ( strcmp( string2. getString(), "-5" ), 0 );
+   EXPECT_EQ( strcmp( string1.getString(), "10" ), 0 );
+   EXPECT_EQ( strcmp( string2.getString(), "-5" ), 0 );
+   EXPECT_EQ( strcmp( string3.getString(), "true" ), 0 );
+   EXPECT_EQ( strcmp( string4.getString(), "false" ), 0 );
+}
+
+TEST( StringTest, SetSize )
+{
+   String str;
+   str.setSize( 42 );
+   EXPECT_EQ( str.getAllocatedSize(), 256 );
+   // it allocates one more byte for the terminating 0
+   str.setSize( 256 );
+   EXPECT_EQ( str.getAllocatedSize(), 512 );
 }
 
 TEST( StringTest, SetString )
 {
    String str1, str2, str3, str4;
 
-   str1. setString( "string1" );
-   str2. setString( "xxxstring2", 3 );
-   str3. setString( "string3xxx", 0, 3 );
-   str4. setString( "xxxstring4xxx", 3, 3 );
+   str1.setString( "string1" );
+   str2.setString( "xxxstring2", 3 );
+   str3.setString( "string3xxx", 0, 3 );
+   str4.setString( "xxxstring4xxx", 3, 3 );
 
-   ASSERT_EQ( strcmp( str1. getString(), "string1" ), 0 );
-   ASSERT_EQ( strcmp( str2. getString(), "string2" ), 0 );
-   ASSERT_EQ( strcmp( str3. getString(), "string3" ), 0 );
-   ASSERT_EQ( strcmp( str4. getString(), "string4" ), 0 );
+   EXPECT_EQ( strcmp( str1.getString(), "string1" ), 0 );
+   EXPECT_EQ( strcmp( str2.getString(), "string2" ), 0 );
+   EXPECT_EQ( strcmp( str3.getString(), "string3" ), 0 );
+   EXPECT_EQ( strcmp( str4.getString(), "string4" ), 0 );
 }
 
 TEST( StringTest, IndexingOperator )
 {
    String str( "1234567890" );
-   ASSERT_EQ( str[ 0 ], '1' );
-   ASSERT_EQ( str[ 1 ], '2' );
-   ASSERT_EQ( str[ 2 ], '3' );
-   ASSERT_EQ( str[ 3 ], '4' );
-   ASSERT_EQ( str[ 4 ], '5' );
-   ASSERT_EQ( str[ 5 ], '6' );
-   ASSERT_EQ( str[ 6 ], '7' );
-   ASSERT_EQ( str[ 7 ], '8' );
-   ASSERT_EQ( str[ 8 ], '9' );
-   ASSERT_EQ( str[ 9 ], '0' );
+   EXPECT_EQ( str[ 0 ], '1' );
+   EXPECT_EQ( str[ 1 ], '2' );
+   EXPECT_EQ( str[ 2 ], '3' );
+   EXPECT_EQ( str[ 3 ], '4' );
+   EXPECT_EQ( str[ 4 ], '5' );
+   EXPECT_EQ( str[ 5 ], '6' );
+   EXPECT_EQ( str[ 6 ], '7' );
+   EXPECT_EQ( str[ 7 ], '8' );
+   EXPECT_EQ( str[ 8 ], '9' );
+   EXPECT_EQ( str[ 9 ], '0' );
 }
 
-TEST( StringTest, AssignmentOperator )
+TEST( StringTest, CStringOperators )
 {
-   String string1( "string" );
-   String string2;
-   string2 = string1;
+   // assignment operator
+   String string1;
+   string1 = "string";
+   EXPECT_EQ( strcmp( string1.getString(), "string" ), 0 );
+
+   // addition
+   string1 += "string2";
+   EXPECT_EQ( strcmp( string1.getString(), "stringstring2" ), 0 );
+
+   // addition that forces a new page allocation
+   string1 += " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long";
+   EXPECT_EQ( strcmp( string1.getString(),
+              "stringstring2"
+              " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long"
+              " long long long long long long long long long long long long long long" ),
+            0 );
+
+   // addition
+   EXPECT_EQ( strcmp( (String( "foo " ) + "bar").getString(), "foo bar" ), 0 );
+   EXPECT_EQ( strcmp( ("foo" + String( " bar" )).getString(), "foo bar" ), 0 );
 
-   ASSERT_EQ( strcmp( string2. getString(), "string" ), 0 );
+   // comparison
+   EXPECT_EQ( String( "foo" ), "foo" );
+   EXPECT_NE( String( "bar" ), "foo" );
+   EXPECT_NE( String( "fooo" ), "foo" );
 }
 
-TEST( StringTest, AdditionAssignmentOperator )
+TEST( StringTest, StringOperators )
 {
+   // assignment
    String string1( "string" );
    String string2;
    string2 = string1;
-   string2 += "string2";
+   EXPECT_EQ( strcmp( string2.getString(), "string" ), 0 );
 
-   ASSERT_EQ( strcmp( string2. getString(), "stringstring2" ), 0 );
+   // addition
+   string1.setString( "foo " );
+   string1 += String( "bar" );
+   EXPECT_EQ( strcmp( string1.getString(), "foo bar" ), 0 );
+
+   // comparison
+   EXPECT_EQ( String( "foo bar" ), string1 );
+   EXPECT_NE( String( "bar" ), string1 );
+   EXPECT_NE( String( "bar" ), String( "baz" ) );
+   EXPECT_NE( String( "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long" ),
+              String( "short" ) );
+   String string3( "long long long long long long long long long long long "
+                   "long long long long long long long long long long long "
+                   "long long long long long long long long long long long "
+                   "long long long long long long long long long long long "
+                   "long long long long long long long long long long long "
+                   "long long long long long long long long long long long" );
+   string3[ 255 ] = 0;
+   EXPECT_EQ( string3,
+              String( "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long long long long long "
+                      "long long long long long long long " ) );
+
+   // addition
+   EXPECT_EQ( String( "foo " ) + String( "bar" ), "foo bar" );
 }
 
+TEST( StringTest, SingleCharacterOperators )
+{
+   // assignment
+   String string1;
+   string1 = 'A';
+   EXPECT_EQ( strcmp( string1.getString(), "A" ), 0 );
+
+   // addition of a single character
+   String string2( "string " );
+   string2 += 'A';
+   EXPECT_EQ( strcmp( string2.getString(), "string A" ), 0 );
+
+   // addition of a single character that causes new page allocation
+   string2.setString( "long long long long long long long long long long long long long "
+                      "long long long long long long long long long long long long long "
+                      "long long long long long long long long long long long long long "
+                      "long long long long long long long long long long long long " );
+   ASSERT_EQ( string2.getLength(), 255 );
+   string2 += 'B';
+   EXPECT_EQ( strcmp( string2.getString(),
+                  "long long long long long long long long long long long long long "
+                  "long long long long long long long long long long long long long "
+                  "long long long long long long long long long long long long long "
+                  "long long long long long long long long long long long long B" ),
+              0 );
+
+   // addition
+   EXPECT_EQ( strcmp( (String( "A " ) + 'B').getString(), "A B" ), 0 );
+   EXPECT_EQ( strcmp( ('A' + String( " B" )).getString(), "A B" ), 0 );
+
+   // comparison
+   EXPECT_EQ( String( "A" ), 'A' );
+   EXPECT_NE( String( "B" ), 'A' );
+   EXPECT_NE( String( "AB" ), 'A' );
+}
+
+TEST( StringTest, CastToBoolOperator )
+{
+   String string;
+   EXPECT_TRUE( ! string );
+   EXPECT_FALSE( string );
+   string.setString( "foo" );
+   EXPECT_TRUE( string );
+   EXPECT_FALSE( ! string );
+}
+
+TEST( StringTest, replace )
+{
+   EXPECT_EQ( String( "string" ).replace( "ing", "bc" ), "strbc" );
+   EXPECT_EQ( String( "abracadabra" ).replace( "ab", "CAT" ), "CATracadCATra" );
+   EXPECT_EQ( String( "abracadabra" ).replace( "ab", "CAT", 1 ), "CATracadabra" );
+}
+
+TEST( StringTest, strip )
+{
+   EXPECT_EQ( String( "string" ).strip(), "string" );
+   EXPECT_EQ( String( "  string" ).strip(), "string" );
+   EXPECT_EQ( String( "string  " ).strip(), "string" );
+   EXPECT_EQ( String( "  string  " ).strip(), "string" );
+   EXPECT_EQ( String( " string1  string2  " ).strip(), "string1  string2" );
+   EXPECT_EQ( String( "" ).strip(), "" );
+   EXPECT_EQ( String( "  " ).strip(), "" );
+}
+
+TEST( StringTest, split )
+{
+   Containers::List< String > list;
+
+   String( "A B C" ).split( list, ' ' );
+   ASSERT_EQ( list.getSize(), 3 );
+   EXPECT_EQ( list[ 0 ], "A" );
+   EXPECT_EQ( list[ 1 ], "B" );
+   EXPECT_EQ( list[ 2 ], "C" );
+
+   String( "abracadabra" ).split( list, 'a' );
+   ASSERT_EQ( list.getSize(), 4 );
+   EXPECT_EQ( list[ 0 ], "br" );
+   EXPECT_EQ( list[ 1 ], "c" );
+   EXPECT_EQ( list[ 2 ], "d" );
+   EXPECT_EQ( list[ 3 ], "br" );
+
+   String( "abracadabra" ).split( list, 'b' );
+   ASSERT_EQ( list.getSize(), 3 );
+   EXPECT_EQ( list[ 0 ], "a" );
+   EXPECT_EQ( list[ 1 ], "racada" );
+   EXPECT_EQ( list[ 2 ], "ra" );
+
+   String( "abracadabra" ).split( list, 'A' );
+   ASSERT_EQ( list.getSize(), 1 );
+   EXPECT_EQ( list[ 0 ], "abracadabra" );
+}
 
 TEST( StringTest, SaveLoad )
 {
    String str1( "testing-string" );
    File file;
-   file.open( "test-file.tnl", tnlWriteMode );
+   file.open( "test-file.tnl", IOMode::write );
    ASSERT_TRUE( str1.save( file ) );
    file.close();
-   file.open( "test-file.tnl", tnlReadMode );
+   file.open( "test-file.tnl", IOMode::read );
    String str2;
    ASSERT_TRUE( str2.load( file ) );
-   ASSERT_EQ( str1, str2 );
-};
+   EXPECT_EQ( str1, str2 );
 
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
+};
 #endif
 
 
+#include "GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
-
diff --git a/src/UnitTests/UniquePointerTest.cpp b/src/UnitTests/UniquePointerTest.cpp
index 579fd2569df3e9b6b68f7e21d426836a7a1abf12..677b3e2bb98a07508ec059b2e6a350375785c9b1 100644
--- a/src/UnitTests/UniquePointerTest.cpp
+++ b/src/UnitTests/UniquePointerTest.cpp
@@ -21,7 +21,7 @@
 #include <TNL/Containers/StaticArray.h>
 
 #ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 #endif
 
 using namespace TNL;
@@ -47,12 +47,13 @@ TEST( UniquePointerTest, ConstructorTest )
 };
 #endif
 
+#include "GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
    return RUN_ALL_TESTS();
 #else
-   return EXIT_FAILURE;
+   throw GtestMissingError();
 #endif
 }
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
old mode 100755
new mode 100644
index 9c155fb82be4c65ca26c24d840c29cec99747d4f..22266594a9b622be6d0345b3d8ec92a33c979878
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -4,5 +4,6 @@ ADD_SUBDIRECTORY( data )
 ADD_SUBDIRECTORY( benchmarks )
 #ADD_SUBDIRECTORY( unit-tests )
 ADD_SUBDIRECTORY( long-time-unit-tests )
+ADD_SUBDIRECTORY( mic )
 
 unset( ENABLE_CODECOVERAGE )
\ No newline at end of file
diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt
old mode 100755
new mode 100644
index 39a5ff2d40750a1b4ba731815e9b634728b61cb9..04f74a2b54a8710b73d67f1a0a9946aa6ad5205e
--- a/tests/benchmarks/CMakeLists.txt
+++ b/tests/benchmarks/CMakeLists.txt
@@ -2,35 +2,30 @@ ADD_SUBDIRECTORY( share )
 ADD_SUBDIRECTORY( heat-equation-benchmark )
 
 IF( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnl-cuda-benchmarks${debugExt} tnl-cuda-benchmarks.cu )
+    CUDA_ADD_EXECUTABLE( tnl-benchmark-blas${debugExt} tnl-benchmark-blas.cu )
     if( HAVE_CUBLAS STREQUAL "yes" )
-        CUDA_ADD_CUBLAS_TO_TARGET( tnl-cuda-benchmarks${debugExt} )
+        CUDA_ADD_CUBLAS_TO_TARGET( tnl-benchmark-blas${debugExt} )
     endif()
-    TARGET_LINK_LIBRARIES( tnl-cuda-benchmarks${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
-    
+    TARGET_LINK_LIBRARIES( tnl-benchmark-blas${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )
+
     CUDA_ADD_EXECUTABLE( tnl-benchmark-spmv${debugExt} tnl-benchmark-spmv.cu )
-    TARGET_LINK_LIBRARIES( tnl-benchmark-spmv${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
-    
+    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 )
-    TARGET_LINK_LIBRARIES( tnl-benchmark-linear-solvers${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
+    TARGET_LINK_LIBRARIES( tnl-benchmark-linear-solvers${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )
 ELSE()
+    ADD_EXECUTABLE( tnl-benchmark-blas${debugExt} tnl-benchmark-blas.cpp )
+    TARGET_LINK_LIBRARIES( tnl-benchmark-blas${debugExt} tnl${debugExt}-${tnlVersion} )
+
     ADD_EXECUTABLE( tnl-benchmark-spmv${debugExt} tnl-benchmark-spmv.cpp )
     TARGET_LINK_LIBRARIES( tnl-benchmark-spmv${debugExt} tnl${debugExt}-${tnlVersion} )
 
-    ADD_EXECUTABLE( tnl-benchmark-linear-solvers${debugExt} tnl-benchmark-linear-solvers.cpp )    
+    ADD_EXECUTABLE( tnl-benchmark-linear-solvers${debugExt} tnl-benchmark-linear-solvers.cpp )
     TARGET_LINK_LIBRARIES( tnl-benchmark-linear-solvers${debugExt} tnl${debugExt}-${tnlVersion} )
 ENDIF()
 
-if( BUILD_CUDA )                                                              
-   INSTALL( TARGETS
-                tnl-cuda-benchmarks${debugExt}
-            RUNTIME DESTINATION bin )
-endif()
-
-INSTALL( TARGETS 
+INSTALL( TARGETS
+            tnl-benchmark-blas${debugExt}
             tnl-benchmark-spmv${debugExt}
-            tnl-benchmark-linear-solvers${debugExt}                 
+            tnl-benchmark-linear-solvers${debugExt}
          RUNTIME DESTINATION bin )
-
-
-                                            
diff --git a/tests/benchmarks/array-operations.h b/tests/benchmarks/array-operations.h
index 890f9ddc490cec0dee85c9c5b7e607f467b2b8bc..504dcc1da03a91fa87af913008f9355579e62930 100644
--- a/tests/benchmarks/array-operations.h
+++ b/tests/benchmarks/array-operations.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          array-operations.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include "benchmarks.h"
@@ -14,7 +26,7 @@ template< typename Real = double,
 bool
 benchmarkArrayOperations( Benchmark & benchmark,
                           const int & loops,
-                          const int & size )
+                          const long & size )
 {
     typedef Containers::Array< Real, Devices::Host, Index > HostArray;
     typedef Containers::Array< Real, Devices::Cuda, Index > CudaArray;
@@ -24,16 +36,12 @@ benchmarkArrayOperations( Benchmark & benchmark,
 
     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";
-        std::cerr << msg << std::endl;
-        benchmark.addErrorMessage( msg );
-        return false;
-    }
+    hostArray.setSize( size );
+    hostArray2.setSize( size );
+#ifdef HAVE_CUDA
+    deviceArray.setSize( size );
+    deviceArray2.setSize( size );
+#endif
 
     Real resultHost, resultDevice;
 
@@ -41,11 +49,15 @@ benchmarkArrayOperations( Benchmark & benchmark,
     // reset functions
     auto reset1 = [&]() {
         hostArray.setValue( 1.0 );
+#ifdef HAVE_CUDA
         deviceArray.setValue( 1.0 );
+#endif
     };
     auto reset2 = [&]() {
         hostArray2.setValue( 1.0 );
+#ifdef HAVE_CUDA
         deviceArray2.setValue( 1.0 );
+#endif
     };
     auto reset12 = [&]() {
         reset1();
@@ -63,9 +75,10 @@ benchmarkArrayOperations( Benchmark & benchmark,
         resultDevice = (int) deviceArray == deviceArray2;
     };
     benchmark.setOperation( "comparison (operator==)", 2 * datasetSize );
-    benchmark.time( reset1,
-                    "CPU", compareHost,
-                    "GPU", compareCuda );
+    benchmark.time( reset1, "CPU", compareHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", compareCuda );
+#endif
 
 
     auto copyAssignHostHost = [&]() {
@@ -75,9 +88,12 @@ benchmarkArrayOperations( Benchmark & benchmark,
         deviceArray = deviceArray2;
     };
     benchmark.setOperation( "copy (operator=)", 2 * datasetSize );
-    double basetime = benchmark.time( reset1,
-                    "CPU", copyAssignHostHost,
-                    "GPU", copyAssignCudaCuda );
+    // copyBasetime is used later inside HAVE_CUDA guard, so the compiler will
+    // complain when compiling without CUDA
+    const double copyBasetime = benchmark.time( reset1, "CPU", copyAssignHostHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", copyAssignCudaCuda );
+#endif
 
 
     auto copyAssignHostCuda = [&]() {
@@ -86,10 +102,12 @@ benchmarkArrayOperations( Benchmark & benchmark,
     auto copyAssignCudaHost = [&]() {
         hostArray = deviceArray;
     };
-    benchmark.setOperation( "copy (operator=)", datasetSize, basetime );
+#ifdef HAVE_CUDA
+    benchmark.setOperation( "copy (operator=)", datasetSize, copyBasetime );
     benchmark.time( reset1,
                     "CPU->GPU", copyAssignHostCuda,
                     "GPU->CPU", copyAssignCudaHost );
+#endif
 
 
     auto setValueHost = [&]() {
@@ -99,9 +117,10 @@ benchmarkArrayOperations( Benchmark & benchmark,
         deviceArray.setValue( 3.0 );
     };
     benchmark.setOperation( "setValue", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", setValueHost,
-                    "GPU", setValueCuda );
+    benchmark.time( reset1, "CPU", setValueHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", setValueCuda );
+#endif
 
 
     auto setSizeHost = [&]() {
@@ -112,12 +131,15 @@ benchmarkArrayOperations( Benchmark & benchmark,
     };
     auto resetSize1 = [&]() {
         hostArray.reset();
+#ifdef HAVE_CUDA
         deviceArray.reset();
+#endif
     };
     benchmark.setOperation( "allocation (setSize)", datasetSize );
-    benchmark.time( resetSize1,
-                    "CPU", setSizeHost,
-                    "GPU", setSizeCuda );
+    benchmark.time( resetSize1, "CPU", setSizeHost );
+#ifdef HAVE_CUDA
+    benchmark.time( resetSize1, "GPU", setSizeCuda );
+#endif
 
 
     auto resetSizeHost = [&]() {
@@ -128,12 +150,15 @@ benchmarkArrayOperations( Benchmark & benchmark,
     };
     auto setSize1 = [&]() {
         hostArray.setSize( size );
+#ifdef HAVE_CUDA
         deviceArray.setSize( size );
+#endif
     };
     benchmark.setOperation( "deallocation (reset)", datasetSize );
-    benchmark.time( setSize1,
-                    "CPU", resetSizeHost,
-                    "GPU", resetSizeCuda );
+    benchmark.time( setSize1, "CPU", resetSizeHost );
+#ifdef HAVE_CUDA
+    benchmark.time( setSize1, "GPU", resetSizeCuda );
+#endif
 
     return true;
 }
diff --git a/tests/benchmarks/benchmarks.h b/tests/benchmarks/benchmarks.h
index 20f3d042f8c676bb4b45ecad131bdcad023c162e..ce5e631a6899170cfeba58911be71e5cc17eb7e6 100644
--- a/tests/benchmarks/benchmarks.h
+++ b/tests/benchmarks/benchmarks.h
@@ -1,3 +1,15 @@
+/***************************************************************************
+                          benchmarks.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include <iostream>
diff --git a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h
index 00d22ea2a39c12e1ba5855bc7852bfbc3fbad48c..51d957f1bf421ecbce3bb8606e6d2b8f0172410a 100644
--- a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h
+++ b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h
@@ -19,8 +19,8 @@ template< typename MeshReal,
 class BenchmarkLaplace< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
 : public Operators::Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
                               Functions::MeshInteriorDomain,
-                              Meshes::Grid< 1, MeshReal, Device, MeshIndex >::getMeshDimensions(),
-                              Meshes::Grid< 1, MeshReal, Device, MeshIndex >::getMeshDimensions(),
+                              Meshes::Grid< 1, MeshReal, Device, MeshIndex >::getMeshDimension(),
+                              Meshes::Grid< 1, MeshReal, Device, MeshIndex >::getMeshDimension(),
                               Real,
                               Index >
 {
@@ -31,7 +31,7 @@ class BenchmarkLaplace< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, In
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
+      enum { Dimension = MeshType::getMeshDimension() };
 
       static String getType();
 
@@ -67,8 +67,8 @@ template< typename MeshReal,
 class BenchmarkLaplace< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index >
 : public Operators::Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
                               Functions::MeshInteriorDomain,
-                              Meshes::Grid< 2, MeshReal, Device, MeshIndex >::getMeshDimensions(),
-                              Meshes::Grid< 2, MeshReal, Device, MeshIndex >::getMeshDimensions(),
+                              Meshes::Grid< 2, MeshReal, Device, MeshIndex >::getMeshDimension(),
+                              Meshes::Grid< 2, MeshReal, Device, MeshIndex >::getMeshDimension(),
                               Real,
                               Index >
 {
@@ -79,7 +79,7 @@ class BenchmarkLaplace< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Ind
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
+      enum { Dimension = MeshType::getMeshDimension() };
 
       static String getType();
 
@@ -115,8 +115,8 @@ template< typename MeshReal,
 class BenchmarkLaplace< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index >
 : public Operators::Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
                               Functions::MeshInteriorDomain,
-                              Meshes::Grid< 3, MeshReal, Device, MeshIndex >::getMeshDimensions(),
-                              Meshes::Grid< 3, MeshReal, Device, MeshIndex >::getMeshDimensions(),
+                              Meshes::Grid< 3, MeshReal, Device, MeshIndex >::getMeshDimension(),
+                              Meshes::Grid< 3, MeshReal, Device, MeshIndex >::getMeshDimension(),
                               Real,
                               Index >
 {
@@ -127,7 +127,7 @@ class BenchmarkLaplace< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Ind
       typedef Device DeviceType;
       typedef Index IndexType;
       typedef Functions::MeshFunction< MeshType > MeshFunctionType;
-      enum { Dimensions = MeshType::getMeshDimensions() };
+      enum { Dimension = MeshType::getMeshDimension() };
 
       static String getType();
 
diff --git a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h
index 7a58b9774432cb080d7d04b3475f646b1dc10960..4e260b0f711851d114f29122e8c02ba299ffcb72 100644
--- a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h
+++ b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h
@@ -37,14 +37,14 @@ operator()( const MeshFunction& u,
     * 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(); 
+    static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimension." ); 
+    static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
 
    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 >(); 
+   const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); 
    return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
 }
 
@@ -68,7 +68,7 @@ getLinearSystemRowLength( const MeshType& mesh,
     * by the Finite difference method.
     */
 
-   return 2*Dimensions + 1;
+   return 2*Dimension + 1;
 }
 
 template< typename MeshReal,
@@ -95,11 +95,11 @@ setMatrixElements( const RealType& time,
     * by the Finite difference method.
     */
 
-    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+    const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); 
    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 >(); 
+   const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); 
    matrixRow.setElement( 0, west,   - lambdaX );
    matrixRow.setElement( 1, center, 2.0 * lambdaX );
    matrixRow.setElement( 2, east,   - lambdaX );
@@ -141,17 +141,17 @@ operator()( const MeshFunction& u,
     * 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(); 
+   /*static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimension." ); 
+   static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); 
+   const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
 
    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 >(); */
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >(); */
 
    const IndexType& xSize = entity.getMesh().getDimensions().x();
    const IndexType& c = entity.getIndex();
@@ -181,7 +181,7 @@ getLinearSystemRowLength( const MeshType& mesh,
     * by the Finite difference method.
     */
 
-   return 2*Dimensions + 1;
+   return 2*Dimension + 1;
 }
 
 template< typename MeshReal,
@@ -208,14 +208,14 @@ setMatrixElements( const RealType& time,
     * by the Finite difference method.
     */
 
-    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+    const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); 
    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 >(); 
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1 >(); 
    matrixRow.setElement( 0, south,  -lambdaY );
    matrixRow.setElement( 1, west,   -lambdaX );
    matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
@@ -259,20 +259,20 @@ operator()( const MeshFunction& u,
     * 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(); 
+    static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimension." ); 
+    static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
 
    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 >(); 
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >(); 
+   const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+   const IndexType& down  = neighborEntities.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;
@@ -298,7 +298,7 @@ getLinearSystemRowLength( const MeshType& mesh,
     * by the Finite difference method.
     */
 
-   return 2*Dimensions + 1;
+   return 2*Dimension + 1;
 }
 
 template< typename MeshReal,
@@ -325,17 +325,17 @@ setMatrixElements( const RealType& time,
     * by the Finite difference method.
     */
 
-    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+    const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); 
    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 >(); 
+   const IndexType& east  = neighborEntities.template getEntityIndex<  1,  0,  0 >(); 
+   const IndexType& west  = neighborEntities.template getEntityIndex< -1,  0,  0 >(); 
+   const IndexType& north = neighborEntities.template getEntityIndex<  0,  1,  0 >(); 
+   const IndexType& south = neighborEntities.template getEntityIndex<  0, -1,  0 >(); 
+   const IndexType& up    = neighborEntities.template getEntityIndex<  0,  0,  1 >(); 
+   const IndexType& down  = neighborEntities.template getEntityIndex<  0,  0, -1 >(); 
    matrixRow.setElement( 0, down,   -lambdaZ );
    matrixRow.setElement( 1, south,  -lambdaY );
    matrixRow.setElement( 2, west,   -lambdaX );
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h
index d80f2293d8514eb189dbee57d7f118059f05d992..96a18586f5a8f03b149f9227b776dca6396be9e6 100644
--- a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h
@@ -23,9 +23,9 @@ template<> struct ConfigTagIndex< HeatEquationBenchmarkBuildConfigTag, long int
 /****
  * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
  */
-template< int Dimensions, typename Real, typename Device, typename Index >
-   struct ConfigTagMesh< HeatEquationBenchmarkBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > >
-      { enum { enabled = ( Dimensions == 2 )  &&
+template< int Dimension, typename Real, typename Device, typename Index >
+   struct ConfigTagMesh< HeatEquationBenchmarkBuildConfigTag, Meshes::Grid< Dimension, Real, Device, Index > >
+      { enum { enabled = ( Dimension == 2 )  &&
                          ConfigTagReal< HeatEquationBenchmarkBuildConfigTag, Real >::enabled &&
                          ConfigTagDevice< HeatEquationBenchmarkBuildConfigTag, Device >::enabled &&
                          ConfigTagIndex< HeatEquationBenchmarkBuildConfigTag, Index >::enabled }; };
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h
index 52b26fb860c6f4f7defce8921095d937c4d3b127..25d6eb81ba931c38b222a81ff120b78d3ff07b6d 100644
--- a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h
@@ -70,7 +70,7 @@ class HeatEquationBenchmarkProblem:
       void bindDofs( const MeshPointer& meshPointer,
                      DofVectorPointer& dofsPointer );
 
-      void getExplicitRHS( const RealType& time,
+      void getExplicitUpdate( const RealType& time,
                            const RealType& tau,
                            const MeshPointer& meshPointer,
                            DofVectorPointer& _uPointer,
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h
index e9e3b5af463addbc9b1411ce779f8616a64c0905..573eab7885f83c8ffb2f26a6a4438b3129258099 100644
--- a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h
@@ -139,17 +139,17 @@ setupLinearSystem( const MeshType& mesh,
                    Matrix& matrix )
 {
    const IndexType dofs = this->getDofs( mesh );
-   typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   CompressedRowsLengthsVectorType rowLengths;
+   typedef typename Matrix::CompressedRowLengthsVector CompressedRowLengthsVectorType;
+   CompressedRowLengthsVectorType rowLengths;
    if( ! rowLengths.setSize( dofs ) )
       return false;
-   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh,
+   Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >( mesh,
                                                                           differentialOperatorPointer,
                                                                           boundaryConditionPointer,
                                                                           rowLengths );
    matrix.setDimensions( dofs, dofs );
-   if( ! matrix.setCompressedRowsLengths( rowLengths ) )
+   if( ! matrix.setCompressedRowLengths( rowLengths ) )
       return false;
    return true;
 }
@@ -267,11 +267,11 @@ boundaryConditionsTemplatedCompact( const GridType* grid,
    }
 }
 
-/*template< typename EntityType, int Dimensions >
-struct EntityPointer : public EntityPointer< EntityType, Dimensions - 1 >
+/*template< typename EntityType, int Dimension >
+struct EntityPointer : public EntityPointer< EntityType, Dimension - 1 >
 {
    __device__ EntityPointer( const EntityType* ptr )
-      : EntityPointer< EntityType, Dimensions - 1 >( ptr ), pointer( ptr )
+      : EntityPointer< EntityType, Dimension - 1 >( ptr ), pointer( ptr )
    {      
    }
    
@@ -354,15 +354,15 @@ heatEquationTemplatedCompact( const GridType* grid,
    {
       GridEntity entity( *grid, coordinates, entityOrientation, entityBasis );
       
-      //entity.refresh();
-      /*if( ! entity.isBoundaryEntity() )
+      entity.refresh();
+      if( ! entity.isBoundaryEntity() )
       {
          fu( entity ) = 
             ( *differentialOperator )( u, entity, time );
 
          typedef Functions::FunctionAdapter< GridType, RightHandSide > FunctionAdapter;
          fu( entity ) +=  FunctionAdapter::getValue( *rightHandSide, entity, time );
-      }*/
+      }
    }
 }
 #endif
@@ -375,7 +375,7 @@ template< typename Mesh,
           typename DifferentialOperator >
 void
 HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getExplicitRHS( const RealType& time,
+getExplicitUpdate( const RealType& time,
                 const RealType& tau,
                 const MeshPointer& mesh,
                 DofVectorPointer& uDofs,
@@ -459,7 +459,7 @@ getExplicitRHS( const RealType& time,
       }
       if( this->cudaKernelType == "templated-compact" )
       {
-         typedef typename MeshType::MeshEntity< 2 > CellType;
+         typedef typename MeshType::EntityType< 2 > CellType;
          //typedef typename MeshType::Cell CellType;
          //std::cerr << "Size of entity is ... " << sizeof( TestEntity< MeshType > ) << " vs. " << sizeof( CellType ) << std::endl;
          typedef typename CellType::CoordinatesType CoordinatesType;
@@ -494,7 +494,7 @@ getExplicitRHS( const RealType& time,
                     gridXIdx,
                     gridYIdx );
          cudaThreadSynchronize();
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          
          //std::cerr << "Computing the heat equation ..." << std::endl;
          for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
@@ -514,7 +514,7 @@ getExplicitRHS( const RealType& time,
                     gridXIdx,
                     gridYIdx );
          cudaThreadSynchronize();         
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
       }
       #endif
       if( this->cudaKernelType == "templated" )
@@ -524,15 +524,12 @@ getExplicitRHS( const RealType& time,
          this->u->bind( mesh, uDofs );
          this->fu->bind( mesh, fuDofs );         
          //explicitUpdater.setGPUTransferTimer( this->gpuTransferTimer ); 
-         this->explicitUpdater.template update< typename Mesh::Cell >( 
-            time,
-            mesh,
-            this->differentialOperatorPointer,
-            this->boundaryConditionPointer,
-            this->rightHandSidePointer,
-            this->u,
-            this->fu );
-            }
+         explicitUpdater.setDifferentialOperator( this->differentialOperatorPointer );
+         explicitUpdater.setBoundaryConditions( this->boundaryConditionPointer );
+         explicitUpdater.setRightHandSide( this->rightHandSidePointer );
+         
+         this->explicitUpdater.template update< typename Mesh::Cell >( time, tau, mesh, this->u, this->fu );
+      }
    }
 }
 
@@ -558,21 +555,15 @@ assemblyLinearSystem( const RealType& time,
                              BoundaryCondition,
                              RightHandSide,
                              Solvers::PDE::BackwardTimeDiscretisation,
-                             typename MatrixPointer::ObjectType,
                              typename DofVectorPointer::ObjectType > systemAssembler;
 
    typedef Functions::MeshFunction< Mesh > MeshFunctionType;
    typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer;
    MeshFunctionPointer u( mesh, *_u );
-   systemAssembler.template assembly< typename Mesh::Cell >( time,
-                                                             tau,
-                                                             mesh,
-                                                             this->differentialOperator,
-                                                             this->boundaryCondition,
-                                                             this->rightHandSide,
-                                                             u,
-                                                             matrix,
-                                                             b );
+   systemAssembler.setDifferentialOperator( this->differentialOperator );
+   systemAssembler.setBoundaryConditions( this->boundaryCondition );
+   systemAssembler.setRightHandSide( this->rightHandSide );
+   systemAssembler.template assembly< typename Mesh::Cell >( time, tau, mesh, u, matrix, b );
 }
 
 template< typename Mesh,
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h
index 393028f2cbf1015705a3d5869a1cf215fa3a3293..dd4f33bc2225fe51796654b2b473b62fe4ea4e06 100644
--- a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h
@@ -2,7 +2,7 @@
 #define HeatEquationBenchmarkRHS_H_
 #include <TNL/Functions/Domain.h>
 template< typename Mesh, typename Real >class HeatEquationBenchmarkRhs
-  : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > 
+  : public Functions::Domain< Mesh::getMeshDimension(), Functions::MeshDomain > 
  {
    public:
 
@@ -20,8 +20,8 @@ template< typename Mesh, typename Real >class HeatEquationBenchmarkRhs
       Real operator()( const MeshEntity& entity,
                        const Real& time = 0.0 ) const
       {
-         typedef typename MeshEntity::MeshType::VertexType VertexType;
-         VertexType v = entity.getCenter();
+         typedef typename MeshEntity::MeshType::PointType PointType;
+         PointType v = entity.getCenter();
          return 0.0;
       }
 };
diff --git a/tests/benchmarks/heat-equation-benchmark/TestGridEntity.h b/tests/benchmarks/heat-equation-benchmark/TestGridEntity.h
index e72140e45871d62fb9ae7926e3aa7a53a9d31642..3492b219807f4650ed665b2ee57c77754f5934f1 100644
--- a/tests/benchmarks/heat-equation-benchmark/TestGridEntity.h
+++ b/tests/benchmarks/heat-equation-benchmark/TestGridEntity.h
@@ -18,12 +18,12 @@
 #pragma once 
  
 template< typename GridEntity >
-class TestNeighbourGridEntitiesStorage
+class TestNeighborGridEntitiesStorage
 {  
    public:
       
       __cuda_callable__
-      TestNeighbourGridEntitiesStorage( const GridEntity& entity )
+      TestNeighborGridEntitiesStorage( const GridEntity& entity )
       : entity( entity )
       {}
       
@@ -31,61 +31,61 @@ class TestNeighbourGridEntitiesStorage
 };
 
 template< typename Grid,          
-          int EntityDimensions >
+          int EntityDimension >
 class TestGridEntity
 {
 };
 
 
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,          
-          int EntityDimensions >
-class TestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, EntityDimensions >
+          int EntityDimension >
+class TestGridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension >
 {
    public:
-      static const int entityDimensions = EntityDimensions;
+      static const int entityDimension = EntityDimension;
 };
 
 /****
  * Specializations for cells
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index >
-class TestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions >
+class TestGridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension >
 {
    public:
       
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
       typedef GridType MeshType;
       typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       //typedef Config ConfigType;
       
-      static const int meshDimensions = GridType::meshDimensions;
+      static const int meshDimension = GridType::meshDimension;
       
-      static const int entityDimensions = meshDimensions;
+      static const int entityDimension = meshDimension;
 
-      constexpr static int getDimensions() { return entityDimensions; };
+      constexpr static int getDimensions() { return entityDimension; };
       
-      constexpr static int getMeshDimensions() { return meshDimensions; };
+      constexpr static int getDimension() { return meshDimension; };
       
       
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType;
-      typedef TestGridEntity< GridType, entityDimensions > ThisType;
-      typedef TestNeighbourGridEntitiesStorage< ThisType > NeighbourGridEntitiesStorageType;
+      typedef Containers::StaticVector< meshDimension, IndexType > EntityOrientationType;
+      typedef Containers::StaticVector< meshDimension, IndexType > EntityBasisType;
+      typedef TestGridEntity< GridType, entityDimension > ThisType;
+      typedef TestNeighborGridEntitiesStorage< ThisType > NeighborGridEntitiesStorageType;
       
       __cuda_callable__ inline
       TestGridEntity( const GridType& grid )
       : grid( grid ),
         /*entityIndex( -1 ),*/
-        neighbourEntitiesStorage( *this )
+        neighborEntitiesStorage( *this )
       {
       }
       
@@ -98,7 +98,7 @@ class TestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimension
       : grid( grid ),
         /*entityIndex( -1 ),
         coordinates( coordinates ),*/
-        neighbourEntitiesStorage( *this )
+        neighborEntitiesStorage( *this )
         {
         }
 
@@ -116,7 +116,7 @@ class TestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimension
       
       EntityBasisType basis;
       
-      NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
+      NeighborGridEntitiesStorageType neighborEntitiesStorage;
       
 };
 
diff --git a/tests/benchmarks/heat-equation-benchmark/pure-c-rhs.h b/tests/benchmarks/heat-equation-benchmark/pure-c-rhs.h
index 8de3a739c094b1935ec88d1ff14d18307da77218..3097d652f0a9928d791854c1eacb2728790dba6e 100644
--- a/tests/benchmarks/heat-equation-benchmark/pure-c-rhs.h
+++ b/tests/benchmarks/heat-equation-benchmark/pure-c-rhs.h
@@ -52,12 +52,12 @@ __global__ void boundaryConditionsKernel( Real* u,
       aux[ j * gridXSize + gridYSize - 1 ] = 0.0;
       u[ j * gridXSize + gridYSize - 1 ] = 0.0; //u[ j * gridXSize + gridXSize - 1 ];      
    }
-   if( j == 0 && i > 0 && i < gridXSize - 1 )
+   if( j == 0 && i < gridXSize )
    {
       aux[ i ] = 0.0; //u[ j * gridXSize + 1 ];
       u[ i ] = 0.0; //u[ j * gridXSize + 1 ];
    }
-   if( j == gridYSize -1  && i > 0 && i < gridXSize - 1 )
+   if( j == gridYSize -1  && i < gridXSize )
    {
       aux[ j * gridXSize + i ] = 0.0; //u[ j * gridXSize + gridXSize - 1 ];      
       u[ j * gridXSize + i ] = 0.0; //u[ j * gridXSize + gridXSize - 1 ];      
@@ -80,9 +80,11 @@ __global__ void heatEquationKernel( const Real* u,
        j > 0 && j < gridYSize - 1 )
    {
       const Index c = j * gridXSize + i;
-      aux[ 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 );
-   }
+      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 );
+      //aux[ c ] = ( ( __ldg( &u[ c - 1 ] ) - 2.0 * __ldg( &u[ c ] ) + __ldg( &u[ c + 1 ] ) ) * hx_inv +
+      //                   ( __ldg( &u[ c - gridXSize ] ) - 2.0 * __ldg( &u[ c ] ) + __ldg( &u[ c + gridXSize ] ) ) * hy_inv );
+   }  
 }
 
 template< typename RealType >
diff --git a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h
index 6cacb6a2be3531c981b77b3cfb7ca46be59db374..3db5347a724356c11cf9afe8407ad7cacb5d4300 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h
@@ -59,10 +59,10 @@ class HeatEquationBenchmarkSetter
 
       static bool run( const Config::ParameterContainer & parameters )
       {
-          enum { Dimensions = MeshType::getMeshDimensions() };
+          enum { Dimension = MeshType::getMeshDimension() };
           typedef BenchmarkLaplace< MeshType, Real, Index > ApproximateOperator;
           typedef HeatEquationBenchmarkRhs< MeshType, Real > RightHandSide;
-          typedef Containers::StaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+          typedef Containers::StaticVector < MeshType::getMeshDimension(), Real > Point;
 
          /****
           * Resolve the template arguments of your solver here.
@@ -72,10 +72,10 @@ class HeatEquationBenchmarkSetter
           String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" );
           if( parameters.checkParameter( "boundary-conditions-constant" ) )
           {
-             typedef Functions::Analytic::Constant< Dimensions, Real > Constant;
+             typedef Functions::Analytic::Constant< Dimension, Real > Constant;
              if( boundaryConditionsType == "dirichlet" )
              {
-                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
                 typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
                 SolverStarter solverStarter;
                 return solverStarter.template run< Problem >( parameters );
@@ -88,7 +88,7 @@ class HeatEquationBenchmarkSetter
           typedef Functions::MeshFunction< MeshType > MeshFunction;
           if( boundaryConditionsType == "dirichlet" )
           {
-             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimension(), Real, Index > BoundaryConditions;
              typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
              SolverStarter solverStarter;
              return solverStarter.template run< Problem >( parameters );
diff --git a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-simple-heat-equation.h b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-simple-heat-equation.h
index 6834ed731da5afeec97f485b4723d176fe741527..04d4e965cb048c4ada8788d09fb22d78fc003c76 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-simple-heat-equation.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-simple-heat-equation.h
@@ -190,20 +190,27 @@ template< typename Real, typename Index >
 __global__ void updateKernel( Real* u,
                               Real* aux,
                               Real* cudaBlockResidue,
-                              const Index dofs )
+                              const Index dofs,
+                              Real tau )
 {
+   extern __shared__ Real du[];
    const Index blockOffset = blockIdx.x * blockDim.x;
    Index idx = blockOffset + threadIdx.x;
  
    if( idx < dofs )
-      u[ idx ] += aux[ idx ];
+   {
+      u[ idx ] += tau * aux[ idx ];
+      du[ threadIdx.x ] = fabs( aux[ idx ] );
+   }
+   else
+      du[ threadIdx.x ] = 0.0;
  
    __syncthreads();
 
    const Index rest = dofs - blockOffset;
    Index n =  rest < blockDim.x ? rest : blockDim.x;
 
-   computeBlockResidue< Real, Index >( aux,
+   computeBlockResidue< Real, Index >( du,
                                        cudaBlockResidue,
                                        n );
 }
@@ -305,11 +312,11 @@ bool solveHeatEquationCuda( const Config::ParameterContainer& parameters,
    }
    
    typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType;
-   typedef typename GridType::VertexType VertexType;
+   typedef typename GridType::PointType PointType;
    typedef SharedPointer< GridType > GridPointer;
    GridPointer gridPointer;
    gridPointer->setDimensions( gridXSize, gridYSize );
-   gridPointer->setDomain( VertexType( 0.0, 0.0 ), VertexType( domainXSize, domainYSize ) );
+   gridPointer->setDomain( PointType( 0.0, 0.0 ), PointType( domainXSize, domainYSize ) );
    Containers::Vector< Real, Devices::Cuda, Index > vecU;
    vecU.bind( cuda_u, gridXSize * gridYSize );
    Functions::MeshFunction< GridType > meshFunction;
@@ -346,29 +353,31 @@ bool solveHeatEquationCuda( const Config::ParameterContainer& parameters,
       const Real timeLeft = finalTime - time;
       const Real currentTau = tau < timeLeft ? tau : timeLeft;    
       
-      if( ! pureCRhsCuda( cudaGridSize, cudaBlockSize, cuda_u, cuda_aux, tau, hx_inv, hy_inv, gridXSize, gridYSize) )
+      if( ! pureCRhsCuda( cudaGridSize, cudaBlockSize, cuda_u, cuda_aux, currentTau, hx_inv, hy_inv, gridXSize, gridYSize) )
          return false;
       computationTimer.stop();
       
-      /*cudaMemcpy( aux, cuda_aux, dofsCount * sizeof( Real ),  cudaMemcpyDeviceToHost );
-      writeFunction( "rhs", aux, gridXSize, gridYSize, hx, hy, domainXSize / 2.0, domainYSize / 2.0 );
-      getchar();*/
-        
+      /*if( iteration % 100 == 0 )
+      {
+         cudaMemcpy( aux, cuda_aux, dofsCount * sizeof( Real ),  cudaMemcpyDeviceToHost );
+         writeFunction( "rhs", aux, gridXSize, gridYSize, hx, hy, domainXSize / 2.0, domainYSize / 2.0 );
+
+         cudaMemcpy( aux, cuda_u, dofsCount * sizeof( Real ),  cudaMemcpyDeviceToHost );
+         writeFunction( "u", aux, gridXSize, gridYSize, hx, hy, domainXSize / 2.0, domainYSize / 2.0 );
+         getchar();
+      }*/      
+      
       updateTimer.start();
       /****
        * Update
        */
       //cout << "Update ... " << std::endl;
-      updateKernel<<< cudaUpdateBlocks, cudaUpdateBlockSize >>>( cuda_u, cuda_aux, cuda_max_du, dofsCount );
+      updateKernel<<< cudaUpdateBlocks, cudaUpdateBlockSize, cudaUpdateBlockSize.x * sizeof( Real ) >>>( cuda_u, cuda_aux, cuda_max_du, dofsCount, tau );
       if( cudaGetLastError() != cudaSuccess )
       {
          std::cerr << "Update failed." << std::endl;
          return false;
-      }
-      /*cudaMemcpy( aux, cuda_u, dofsCount * sizeof( Real ),  cudaMemcpyDeviceToHost );
-      writeFunction( "u", aux, gridXSize, gridYSize, hx, hy, domainXSize / 2.0, domainYSize / 2.0 );
-      getchar();*/
-      
+      }            
       
       cudaThreadSynchronize();
       cudaMemcpy( max_du, cuda_max_du, cudaUpdateBlocks.x * sizeof( Real ), cudaMemcpyDeviceToHost );
@@ -391,12 +400,18 @@ bool solveHeatEquationCuda( const Config::ParameterContainer& parameters,
          cout << "Iteration: " << iteration << "\t Time:" << time << "    \r" << flush;                 
    }
    timer.stop();
+   if( verbose )
+     cout << endl;
+   
    //cudaMemcpy( u, cuda_u, dofsCount * sizeof( Real ), cudaMemcpyDeviceToHost );
    //writeFunction( "final", u, gridXSize, gridYSize, hx, hy, domainXSize / 2.0, domainYSize / 2.0 );
 
    /****
     * Saving the result
     */
+   if( verbose )
+     std::cout << "Saving result..." << std::endl;
+   
    meshFunction.save( "simple-heat-equation-result.tnl" );
    
    /***
@@ -496,18 +511,6 @@ bool solveHeatEquationHost( const Config::ParameterContainer& parameters,
          aux[ ( gridYSize - 1 ) * gridXSize + i ] = 0.0; //u[ ( gridYSize - 2 ) * gridXSize + i ];
       }
  
-      /*for( Index j = 1; j < gridYSize - 1; j++ )
-         for( Index i = 1; i < gridXSize - 1; i++ )
-         {
-            const Index c = j * gridXSize + i;
-            aux[ c ] = u[ c ] + currentTau * ( ( u[ c - 1 ] - 2.0 * u[ c ] + u[ c + 1 ] ) * hx_inv +
-                                               ( u[ c - gridXSize ] - 2.0 * u[ c ] + u[ c + gridXSize ] ) * hy_inv );
-         }
-      Real* swap = aux;
-      aux = u;
-      u = swap;
-      */
-
       for( Index j = 1; j < gridYSize - 1; j++ )
          for( Index i = 1; i < gridXSize - 1; i++ )
          {
@@ -535,15 +538,18 @@ bool solveHeatEquationHost( const Config::ParameterContainer& parameters,
         std::cout << "Iteration: " << iteration << "\t \t Time:" << time << "    \r" << std::flush;
    }
    timer.stop();
+   if( verbose )
+     cout << endl;
+
    
    /****
     * Saving the result
     */
    typedef Meshes::Grid< 2, Real, Devices::Host, Index > GridType;
-   typedef typename GridType::VertexType VertexType;
+   typedef typename GridType::PointType PointType;
    SharedPointer< GridType > gridPointer;
    gridPointer->setDimensions( gridXSize, gridYSize );
-   gridPointer->setDomain( VertexType( 0.0, 0.0 ), VertexType( domainXSize, domainYSize ) );
+   gridPointer->setDomain( PointType( 0.0, 0.0 ), PointType( domainXSize, domainYSize ) );
    Containers::Vector< Real, Devices::Host, Index > vecU;
    vecU.bind( u, gridXSize * gridYSize );
    Functions::MeshFunction< GridType > meshFunction;
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
index ba6774b30c902b5b3c720742f79a5046b4876f64..c10cec6ee9fa2a2f5762bcac0c80607c2a3d8326 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
@@ -14,10 +14,10 @@
 
 #include <core/tnlObject.h>
 #include <core/Devices::Host.h>
-#include <core/vectors/tnlStaticVector.h>
-#include <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <TNL/Containers/Vector.h>
 
-template< int Dimensions,
+template< int Dimension,
           typename Real = double,
           typename Device = Devices::Host,
           typename Index = int >
@@ -32,12 +32,12 @@ class Grid : public tnlObject
 #include <mesh/grids/GridEntityTopology.h>
 #include <mesh/grids/GridEntityGetter.h>
 #include <mesh/grids/GridEntityConfig.h>
-#include <mesh/grids/NeighbourGridEntityGetter.h>
+#include <mesh/grids/NeighborGridEntityGetter.h>
 #include <core/tnlLogger.h>
 
 // TODO: remove this
 //#include <../tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h>
-//#include <../tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter2D_impl.h>
+//#include <../tests/benchmarks/heat-equation-benchmark/tnlTestNeighborGridEntityGetter2D_impl.h>
 /////
 
 template< typename Real,
@@ -50,41 +50,41 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef tnlStaticVector< 2, Real > VertexType;
-   typedef tnlStaticVector< 2, Index > CoordinatesType;
+   typedef Containers::StaticVector< 2, Real > PointType;
+   typedef Containers::StaticVector< 2, Index > CoordinatesType;
    typedef Meshes::Grid< 2, Real, Devices::Host, Index > HostType;
    typedef Meshes::Grid< 2, Real, tnlCuda, Index > CudaType;   
    typedef Meshes::Grid< 2, Real, Device, Index > ThisType;
    
-   static const int meshDimensions = 2;
+   static const int meshDimension = 2;
 
-   //template< int EntityDimensions, 
+   //template< int EntityDimension, 
    //          typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   //using MeshEntity = GridEntity< ThisType, EntityDimensions, Config >;
+   //using MeshEntity = GridEntity< ThisType, EntityDimension, Config >;
    
-   //typedef MeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
-   //typedef MeshEntity< meshDimensions - 1, GridEntityNoStencilStorage > Face;
-   //typedef MeshEntity< 0 > Vertex;
+   //typedef MeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell;
+   //typedef MeshEntity< meshDimension - 1, GridEntityNoStencilStorage > Face;
+   //typedef MeshEntity< 0 > Point;
    
 
    // TODO: remove this
-   template< int EntityDimensions, 
+   template< int EntityDimension, 
              typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimensions, Config >;
-   typedef TestMeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > TestCell;
+   using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimension, Config >;
+   typedef TestMeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > TestCell;
    /////
    
-   static constexpr int getMeshDimensions() { return meshDimensions; };
+   static constexpr int getMeshDimension() { return meshDimension; };
 
    Grid();
 
-   static tnlString getType();
+   static String getType();
 
-   tnlString getTypeVirtual() const;
+   String getTypeVirtual() const;
 
-   static tnlString getSerializationType();
+   static String getSerializationType();
 
-   virtual tnlString getSerializationTypeVirtual() const;
+   virtual String getSerializationTypeVirtual() const;
 
    void setDimensions( const Index xSize, const Index ySize );
 
@@ -93,13 +93,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    __cuda_callable__
    inline const CoordinatesType& getDimensions() const;
 
-   void setDomain( const VertexType& origin,
-                   const VertexType& proportions );
+   void setDomain( const PointType& origin,
+                   const PointType& proportions );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   inline const PointType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   inline const PointType& getProportions() const;
 
    template< typename EntityType >
    __cuda_callable__
@@ -121,7 +121,7 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    RealType getCellMeasure() const;
    
    __cuda_callable__
-   inline VertexType getSpaceSteps() const;
+   inline PointType getSpaceSteps() const;
 
    template< int xPow, int yPow >
    __cuda_callable__
@@ -153,17 +153,17 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    //! Method for restoring the object from a file
    bool load( tnlFile& file );
 
-   bool save( const tnlString& fileName ) const;
+   bool save( const String& fileName ) const;
 
-   bool load( const tnlString& fileName );
+   bool load( const String& fileName );
 
-   bool writeMesh( const tnlString& fileName,
-                   const tnlString& format ) const;
+   bool writeMesh( const String& fileName,
+                   const String& format ) const;
 
    template< typename MeshFunction >
    bool write( const MeshFunction& function,
-               const tnlString& fileName,
-               const tnlString& format ) const;
+               const String& fileName,
+               const String& format ) const;
 
    void writeProlog( tnlLogger& logger );
 
@@ -176,9 +176,9 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    
    IndexType numberOfCells, numberOfNxFaces, numberOfNyFaces, numberOfFaces, numberOfVertices;
 
-   VertexType origin, proportions;
+   PointType origin, proportions;
    
-   VertexType spaceSteps;
+   PointType spaceSteps;
    
    RealType spaceStepsProducts[ 5 ][ 5 ];
   
@@ -189,10 +189,10 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
 
 #include <fstream>
 #include <iomanip>
-#include <core/tnlAssert.h>
+#include <core/tnlTNL_ASSERT.h>
 #include <mesh/GnuplotWriter.h>
 #include <mesh/grids/GridEntityGetter_impl.h>
-#include <mesh/grids/NeighbourGridEntityGetter2D_impl.h>
+#include <mesh/grids/NeighborGridEntityGetter2D_impl.h>
 #include <mesh/grids/GridEntityMeasureGetter.h>
 
 using namespace std;
@@ -212,19 +212,19 @@ Meshes::Grid< 2, Real, Device, Index > :: Grid()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getType()
+String Meshes::Grid< 2, Real, Device, Index > :: getType()
 {
-   return tnlString( "Meshes::Grid< " ) +
-          tnlString( getMeshDimensions() ) + ", " +
-          tnlString( ::getType< RealType >() ) + ", " +
-          tnlString( Device :: getDeviceType() ) + ", " +
-          tnlString( ::getType< IndexType >() ) + " >";
+   return TNL::String( "Meshes::Grid< " ) +
+          TNL::String( getMeshDimension() ) + ", " +
+          TNL::String( ::getType< RealType >() ) + ", " +
+          TNL::String( Device :: getDeviceType() ) + ", " +
+          TNL::String( ::getType< IndexType >() ) + " >";
 }
 
 template< typename Real,
            typename Device,
            typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
+String Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
 {
    return this->getType();
 }
@@ -232,7 +232,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
+String Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
 {
    return HostType::getType();
 };
@@ -240,7 +240,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const
+String Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
@@ -310,8 +310,8 @@ template< typename Real,
           typename Index >
 void Meshes::Grid< 2, Real, Device, Index > :: setDimensions( const Index xSize, const Index ySize )
 {
-   tnlAssert( xSize > 0, cerr << "xSize = " << xSize );
-   tnlAssert( ySize > 0, cerr << "ySize = " << ySize );
+   tnlTNL_ASSERT( xSize > 0, cerr << "xSize = " << xSize );
+   tnlTNL_ASSERT( ySize > 0, cerr << "ySize = " << ySize );
 
    this->dimensions.x() = xSize;
    this->dimensions.y() = ySize;
@@ -344,8 +344,8 @@ Meshes::Grid< 2, Real, Device, Index > :: getDimensions() const
 template< typename Real,
           typename Device,
           typename Index >
-void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const VertexType& origin,
-                                                     const VertexType& proportions )
+void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const PointType& origin,
+                                                     const PointType& proportions )
 {
    this->origin = origin;
    this->proportions = proportions;
@@ -356,7 +356,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline 
-const typename Meshes::Grid< 2, Real, Device, Index >::VertexType&
+const typename Meshes::Grid< 2, Real, Device, Index >::PointType&
 Meshes::Grid< 2, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
@@ -366,7 +366,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline 
-const typename Meshes::Grid< 2, Real, Device, Index > :: VertexType&
+const typename Meshes::Grid< 2, Real, Device, Index > :: PointType&
    Meshes::Grid< 2, Real, Device, Index > :: getProportions() const
 {
    return this->proportions;
@@ -381,10 +381,10 @@ Index
 Meshes::Grid< 2, Real, Device, Index >:: 
 getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
-   switch( EntityType::entityDimensions )
+   switch( EntityType::entityDimension )
    {
       case 2:
          return this->numberOfCells;
@@ -405,8 +405,8 @@ EntityType
 Meshes::Grid< 2, Real, Device, Index >::
 getEntity( const IndexType& entityIndex ) const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
    return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex );
 }
@@ -420,8 +420,8 @@ Index
 Meshes::Grid< 2, Real, Device, Index >::
 getEntityIndex( const EntityType& entity ) const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
    return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
 }
@@ -454,7 +454,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-typename Meshes::Grid< 2, Real, Device, Index >::VertexType
+typename Meshes::Grid< 2, Real, Device, Index >::PointType
 Meshes::Grid< 2, Real, Device, Index >::
 getSpaceSteps() const
 {
@@ -470,9 +470,9 @@ const Real&
 Meshes::Grid< 2, Real, Device, Index >::
 getSpaceStepsProducts() const
 {
-   tnlAssert( xPow >= -2 && xPow <= 2, 
+   tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, 
               cerr << " xPow = " << xPow );
-   tnlAssert( yPow >= -2 && yPow <= 2, 
+   tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, 
               cerr << " yPow = " << yPow );
 
    return this->spaceStepsProducts[ yPow + 2 ][ xPow + 2 ];
@@ -596,7 +596,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( tnlFile& file )
 template< typename Real,
           typename Device,
           typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) const
+bool Meshes::Grid< 2, Real, Device, Index > :: save( const String& fileName ) const
 {
    return tnlObject :: save( fileName );
 };
@@ -604,7 +604,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName )
 template< typename Real,
            typename Device,
            typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName )
+bool Meshes::Grid< 2, Real, Device, Index > :: load( const String& fileName )
 {
    return tnlObject :: load( fileName );
 };
@@ -612,8 +612,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName )
 template< typename Real,
           typename Device,
           typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
-                                                     const tnlString& format ) const
+bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
+                                                     const String& format ) const
 {
    fstream file;
    file. open( fileName. getString(), ios :: out );
@@ -630,7 +630,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
            << endl << endl;
       MeshEntity< 0 > vertex( *this );
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
-      VertexType v;
+      PointType v;
       for( Index j = 0; j < this->dimensions. y(); j ++ )
       {
          file << "draw( ";
@@ -682,13 +682,13 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
       for( Index i = 0; i < this->dimensions. x(); i ++ )
          for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
-            VertexType v1, v2, c;
+            PointType 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->getPoint( CoordinatesType( i + 1, j ), v1 );
+            v2 = this->getPoint( CoordinatesType( i + 1, j + 1 ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -698,8 +698,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * West edge normal
              */
-            /*this->getVertex< -1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< -1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< -1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -709,8 +709,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * North edge normal
              */
-            /*this->getVertex< 1, 1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, 1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, 1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -720,8 +720,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * South edge normal
              */
-            /*this->getVertex< 1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, -1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, -1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, -1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -739,8 +739,8 @@ template< typename Real,
            typename Index >
    template< typename MeshFunction >
 bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& function,
-                                                 const tnlString& fileName,
-                                                 const tnlString& format ) const
+                                                 const String& fileName,
+                                                 const String& format ) const
 {
    if( this->template getEntitiesCount< Cell >() != function. getSize() )
    {
@@ -765,7 +765,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& functi
       {
          for( cellCoordinates.x() = 0; cellCoordinates.x() < getDimensions(). x(); cellCoordinates.x() ++ )
          {
-            VertexType v = cell.getCenter();
+            PointType v = cell.getCenter();
             GnuplotWriter::write( file,  v );
             GnuplotWriter::write( file,  function[ this->getEntityIndex( cell ) ] );
             file << endl;
@@ -784,7 +784,7 @@ void
 Meshes::Grid< 2, Real, Device, Index >::
 writeProlog( tnlLogger& logger )
 {
-   logger.writeParameter( "Dimensions:", getMeshDimensions() );
+   logger.writeParameter( "Dimension:", getMeshDimension() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
@@ -801,7 +801,7 @@ writeProlog( tnlLogger& logger )
 
 #ifdef UNDEF
 
-template< int Dimensions,
+template< int Dimension,
           typename Real = double,
           typename Device = Devices::Host,
           typename Index = int >
@@ -826,41 +826,41 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    typedef Real RealType;
    typedef Device DeviceType;
    typedef Index IndexType;
-   typedef tnlStaticVector< 2, Real > VertexType;
-   typedef tnlStaticVector< 2, Index > CoordinatesType;
+   typedef Containers::StaticVector< 2, Real > PointType;
+   typedef Containers::StaticVector< 2, Index > CoordinatesType;
    typedef Meshes::Grid< 2, Real, Devices::Host, Index > HostType;
    typedef Meshes::Grid< 2, Real, tnlCuda, Index > CudaType;   
    typedef Meshes::Grid< 2, Real, Device, Index > ThisType;
    
-   static const int meshDimensions = 2;
+   static const int meshDimension = 2;
 
-   /*template< int EntityDimensions, 
+   /*template< int EntityDimension, 
              typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   using MeshEntity = GridEntity< ThisType, EntityDimensions, Config >;
+   using MeshEntity = GridEntity< ThisType, EntityDimension, Config >;
    
-   typedef MeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
-   typedef MeshEntity< meshDimensions - 1, GridEntityNoStencilStorage > Face;
-   typedef MeshEntity< 0 > Vertex;*/
+   typedef MeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell;
+   typedef MeshEntity< meshDimension - 1, GridEntityNoStencilStorage > Face;
+   typedef MeshEntity< 0 > Point;*/
    
 
    // TODO: remove this
-   template< int EntityDimensions, 
+   template< int EntityDimension, 
              typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
-   using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimensions, Config >;
-   typedef TestMeshEntity< meshDimensions, GridEntityCrossStencilStorage< 1 > > Cell;
+   using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimension, Config >;
+   typedef TestMeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell;
    /////
    
-   static constexpr int getMeshDimensions() { return meshDimensions; };
+   static constexpr int getMeshDimension() { return meshDimension; };
 
    Grid();
 
-   static tnlString getType();
+   static String getType();
 
-   tnlString getTypeVirtual() const;
+   String getTypeVirtual() const;
 
-   static tnlString getSerializationType();
+   static String getSerializationType();
 
-   virtual tnlString getSerializationTypeVirtual() const;
+   virtual String getSerializationTypeVirtual() const;
 
    void setDimensions( const Index xSize, const Index ySize );
 
@@ -869,13 +869,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    __cuda_callable__
    inline const CoordinatesType& getDimensions() const;
 
-   void setDomain( const VertexType& origin,
-                   const VertexType& proportions );
+   void setDomain( const PointType& origin,
+                   const PointType& proportions );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   inline const PointType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   inline const PointType& getProportions() const;
 
    template< typename EntityType >
    __cuda_callable__
@@ -897,7 +897,7 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    RealType getCellMeasure() const;
    
    __cuda_callable__
-   inline VertexType getSpaceSteps() const;
+   inline PointType getSpaceSteps() const;
 
    template< int xPow, int yPow >
    __cuda_callable__
@@ -929,17 +929,17 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    //! Method for restoring the object from a file
    bool load( tnlFile& file );
 
-   bool save( const tnlString& fileName ) const;
+   bool save( const String& fileName ) const;
 
-   bool load( const tnlString& fileName );
+   bool load( const String& fileName );
 
-   bool writeMesh( const tnlString& fileName,
-                   const tnlString& format ) const;
+   bool writeMesh( const String& fileName,
+                   const String& format ) const;
 
    template< typename MeshFunction >
    bool write( const MeshFunction& function,
-               const tnlString& fileName,
-               const tnlString& format ) const;
+               const String& fileName,
+               const String& format ) const;
 
    void writeProlog( tnlLogger& logger );
 
@@ -952,9 +952,9 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
    
    IndexType numberOfCells, numberOfNxFaces, numberOfNyFaces, numberOfFaces, numberOfVertices;
 
-   VertexType origin, proportions;
+   PointType origin, proportions;
    
-   VertexType spaceSteps;
+   PointType spaceSteps;
    
    RealType spaceStepsProducts[ 5 ][ 5 ];
   
@@ -977,19 +977,19 @@ Meshes::Grid< 2, Real, Device, Index > :: Grid()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getType()
+String Meshes::Grid< 2, Real, Device, Index > :: getType()
 {
-   return tnlString( "Meshes::Grid< " ) +
-          tnlString( getMeshDimensions() ) + ", " +
-          tnlString( ::getType< RealType >() ) + ", " +
-          tnlString( Device :: getDeviceType() ) + ", " +
-          tnlString( ::getType< IndexType >() ) + " >";
+   return TNL::String( "Meshes::Grid< " ) +
+          TNL::String( getMeshDimension() ) + ", " +
+          TNL::String( ::getType< RealType >() ) + ", " +
+          TNL::String( Device :: getDeviceType() ) + ", " +
+          TNL::String( ::getType< IndexType >() ) + " >";
 }
 
 template< typename Real,
            typename Device,
            typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
+String Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
 {
    return this->getType();
 }
@@ -997,7 +997,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
+String Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
 {
    return HostType::getType();
 };
@@ -1005,7 +1005,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const
+String Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
@@ -1075,8 +1075,8 @@ template< typename Real,
           typename Index >
 void Meshes::Grid< 2, Real, Device, Index > :: setDimensions( const Index xSize, const Index ySize )
 {
-   tnlAssert( xSize > 0, cerr << "xSize = " << xSize );
-   tnlAssert( ySize > 0, cerr << "ySize = " << ySize );
+   tnlTNL_ASSERT( xSize > 0, cerr << "xSize = " << xSize );
+   tnlTNL_ASSERT( ySize > 0, cerr << "ySize = " << ySize );
 
    this->dimensions.x() = xSize;
    this->dimensions.y() = ySize;
@@ -1109,8 +1109,8 @@ Meshes::Grid< 2, Real, Device, Index > :: getDimensions() const
 template< typename Real,
           typename Device,
           typename Index >
-void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const VertexType& origin,
-                                                     const VertexType& proportions )
+void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const PointType& origin,
+                                                     const PointType& proportions )
 {
    this->origin = origin;
    this->proportions = proportions;
@@ -1121,7 +1121,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline 
-const typename Meshes::Grid< 2, Real, Device, Index >::VertexType&
+const typename Meshes::Grid< 2, Real, Device, Index >::PointType&
 Meshes::Grid< 2, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
@@ -1131,7 +1131,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline 
-const typename Meshes::Grid< 2, Real, Device, Index > :: VertexType&
+const typename Meshes::Grid< 2, Real, Device, Index > :: PointType&
    Meshes::Grid< 2, Real, Device, Index > :: getProportions() const
 {
    return this->proportions;
@@ -1146,10 +1146,10 @@ Index
 Meshes::Grid< 2, Real, Device, Index >:: 
 getEntitiesCount() const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
-   switch( EntityType::entityDimensions )
+   switch( EntityType::entityDimension )
    {
       case 2:
          return this->numberOfCells;
@@ -1170,8 +1170,8 @@ EntityType
 Meshes::Grid< 2, Real, Device, Index >::
 getEntity( const IndexType& entityIndex ) const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
    return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex );
 }
@@ -1185,8 +1185,8 @@ Index
 Meshes::Grid< 2, Real, Device, Index >::
 getEntityIndex( const EntityType& entity ) const
 {
-   static_assert( EntityType::entityDimensions <= 2 &&
-                  EntityType::entityDimensions >= 0, "Wrong grid entity dimensions." );
+   static_assert( EntityType::entityDimension <= 2 &&
+                  EntityType::entityDimension >= 0, "Wrong grid entity dimension." );
    
    return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
 }
@@ -1219,7 +1219,7 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-typename Meshes::Grid< 2, Real, Device, Index >::VertexType
+typename Meshes::Grid< 2, Real, Device, Index >::PointType
 Meshes::Grid< 2, Real, Device, Index >::
 getSpaceSteps() const
 {
@@ -1235,9 +1235,9 @@ const Real&
 Meshes::Grid< 2, Real, Device, Index >::
 getSpaceStepsProducts() const
 {
-   tnlAssert( xPow >= -2 && xPow <= 2, 
+   tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, 
               cerr << " xPow = " << xPow );
-   tnlAssert( yPow >= -2 && yPow <= 2, 
+   tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, 
               cerr << " yPow = " << yPow );
 
    return this->spaceStepsProducts[ yPow + 2 ][ xPow + 2 ];
@@ -1361,7 +1361,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( tnlFile& file )
 template< typename Real,
           typename Device,
           typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) const
+bool Meshes::Grid< 2, Real, Device, Index > :: save( const String& fileName ) const
 {
    return tnlObject :: save( fileName );
 };
@@ -1369,7 +1369,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName )
 template< typename Real,
            typename Device,
            typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName )
+bool Meshes::Grid< 2, Real, Device, Index > :: load( const String& fileName )
 {
    return tnlObject :: load( fileName );
 };
@@ -1377,8 +1377,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName )
 template< typename Real,
           typename Device,
           typename Index >
-bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
-                                                     const tnlString& format ) const
+bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName,
+                                                     const String& format ) const
 {
    fstream file;
    file. open( fileName. getString(), ios :: out );
@@ -1395,7 +1395,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
            << endl << endl;
       TestMeshEntity< 0 > vertex( *this );
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
-      VertexType v;
+      PointType v;
       for( Index j = 0; j < this->dimensions. y(); j ++ )
       {
          file << "draw( ";
@@ -1447,13 +1447,13 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
       for( Index i = 0; i < this->dimensions. x(); i ++ )
          for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
-            VertexType v1, v2, c;
+            PointType 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->getPoint( CoordinatesType( i + 1, j ), v1 );
+            v2 = this->getPoint( CoordinatesType( i + 1, j + 1 ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -1463,8 +1463,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * West edge normal
              */
-            /*this->getVertex< -1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< -1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< -1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -1474,8 +1474,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * North edge normal
              */
-            /*this->getVertex< 1, 1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, 1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, 1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -1485,8 +1485,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileN
             /****
              * South edge normal
              */
-            /*this->getVertex< 1, -1 >( CoordinatesType( i, j ), v1 );
-            this->getVertex< -1, -1 >( CoordinatesType( i, j ), v2 );
+            /*this->getPoint< 1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getPoint< -1, -1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
             this->getEdgeNormal< 0, -1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
@@ -1504,8 +1504,8 @@ template< typename Real,
            typename Index >
    template< typename MeshFunction >
 bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& function,
-                                                 const tnlString& fileName,
-                                                 const tnlString& format ) const
+                                                 const String& fileName,
+                                                 const String& format ) const
 {
    if( this->template getEntitiesCount< Cell >() != function. getSize() )
    {
@@ -1530,7 +1530,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& functi
       {
          for( cellCoordinates.x() = 0; cellCoordinates.x() < getDimensions(). x(); cellCoordinates.x() ++ )
          {
-            VertexType v = cell.getCenter();
+            PointType v = cell.getCenter();
             GnuplotWriter::write( file,  v );
             GnuplotWriter::write( file,  function[ this->getEntityIndex( cell ) ] );
             file << endl;
@@ -1549,7 +1549,7 @@ void
 Meshes::Grid< 2, Real, Device, Index >::
 writeProlog( tnlLogger& logger )
 {
-   logger.writeParameter( "Dimensions:", getMeshDimensions() );
+   logger.writeParameter( "Dimension:", getMeshDimension() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
index db0228ff1685026ca9a9a55b86ba1195fa58f4b0..aa8bd8d057309b1cd48fe38d71eab7886ccc0d7c 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
@@ -18,7 +18,7 @@
 #pragma once
 
 template< typename Grid,          
-          int EntityDimensions,
+          int EntityDimension,
           typename Config >
 class tnlTestGridEntity
 {
@@ -27,51 +27,51 @@ class tnlTestGridEntity
 /****
  * Specializations for cells
  */
-template< int Dimensions,
+template< int Dimension,
           typename Real,
           typename Device,
           typename Index,
           typename Config >
-class tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimensions, Config >
+class tnlTestGridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >
 {
    public:
       
-      typedef Meshes::Grid< Dimensions, Real, Device, Index > GridType;
+      typedef Meshes::Grid< Dimension, Real, Device, Index > GridType;
       typedef GridType MeshType;
       typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef typename GridType::VertexType VertexType;
+      typedef typename GridType::PointType PointType;
       typedef Config ConfigType;
       
-      static const int meshDimensions = GridType::meshDimensions;
+      static const int meshDimension = GridType::meshDimension;
       
-      static const int entityDimensions = meshDimensions;
+      static const int entityDimension = meshDimension;
 
-      constexpr static int getDimensions() { return entityDimensions; };
+      constexpr static int getDimension() { return entityDimension; };
       
-      constexpr static int getMeshDimensions() { return meshDimensions; };
+      constexpr static int getDimension() { return meshDimension; };
       
       
-      typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType;
-      typedef tnlTestGridEntity< GridType, entityDimensions, Config > ThisType;
-      //typedef tnlTestNeighbourGridEntitiesStorage< ThisType > NeighbourGridEntitiesStorageType;
+      typedef TNL::Containers::StaticVector< meshDimension, IndexType > EntityOrientationType;
+      typedef TNL::Containers::StaticVector< meshDimension, IndexType > EntityBasisType;
+      typedef tnlTestGridEntity< GridType, entityDimension, Config > ThisType;
+      //typedef tnlTestNeighborGridEntitiesStorage< ThisType > NeighborGridEntitiesStorageType;
       
-      /*template< int NeighbourEntityDimensions = entityDimensions >
-      using NeighbourEntities = 
-         tnlTestNeighbourGridEntityGetter<
-            tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >,
-                           entityDimensions,
+      /*template< int NeighborEntityDimension = entityDimension >
+      using NeighborEntities = 
+         tnlTestNeighborGridEntityGetter<
+            tnlTestGridEntity< Meshes::Grid< Dimension, Real, Device, Index >,
+                           entityDimension,
                            Config >,
-            NeighbourEntityDimensions >;*/
+            NeighborEntityDimension >;*/
 
 
       __cuda_callable__ inline
       tnlTestGridEntity( const GridType& grid )
       : grid( grid ),
         entityIndex( -1 )/*,
-        neighbourEntitiesStorage( *this )*/
+        neighborEntitiesStorage( *this )*/
       {
          this->coordinates = CoordinatesType( ( Index ) 0 );
          this->orientation = EntityOrientationType( ( Index ) 0 );
@@ -87,7 +87,7 @@ class tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimens
       : grid( grid ),
         entityIndex( -1 ),
         coordinates( coordinates )/*,
-        neighbourEntitiesStorage( *this )*/
+        neighborEntitiesStorage( *this )*/
       {
          this->orientation = EntityOrientationType( ( Index ) 0 );
          this->basis = EntityBasisType( ( Index ) 1 );
@@ -107,7 +107,7 @@ class tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimens
       
       EntityBasisType basis;
       
-      //NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
+      //NeighborGridEntitiesStorageType neighborEntitiesStorage;
       
 };
 
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntitiesStorage.h b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntitiesStorage.h
index 410aa195976294a6681c44c7591c82c66135870c..f066ef3e3d2ea95531ddbdcbf27714d2f551875c 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntitiesStorage.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntitiesStorage.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnlTestNeighbourGridEntitiesStorage.h  -  description
+                          tnlTestNeighborGridEntitiesStorage.h  -  description
                              -------------------
     begin                : Dec 18, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -19,24 +19,24 @@
 #pragma once
 
 #include <core/tnlCuda.h>
-#include <mesh/MeshDimensionsTag.h>
-#include "tnlTestNeighbourGridEntityGetter.h"
+#include <mesh/MeshDimensionTag.h>
+#include "tnlTestNeighborGridEntityGetter.h"
 
 template< typename GridEntity,
-          int NeighbourEntityDimensions >
-class tnlTestNeighbourGridEntityLayer 
-: public tnlTestNeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1 >
+          int NeighborEntityDimension >
+class tnlTestNeighborGridEntityLayer 
+: public tnlTestNeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1 >
 {   
    public:
       
-      typedef tnlTestNeighbourGridEntityLayer< GridEntity, NeighbourEntityDimensions - 1 > BaseType;
-      typedef tnlTestNeighbourGridEntityGetter< GridEntity, NeighbourEntityDimensions > NeighbourEntityGetterType;
+      typedef tnlTestNeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1 > BaseType;
+      typedef tnlTestNeighborGridEntityGetter< GridEntity, NeighborEntityDimension > NeighborEntityGetterType;
       
-      using BaseType::getNeighbourEntities;
+      using BaseType::getNeighborEntities;
       
       __cuda_callable__
-      tnlTestNeighbourGridEntityLayer( const GridEntity& entity )
-      : neighbourEntities( entity ),
+      tnlTestNeighborGridEntityLayer( const GridEntity& entity )
+      : neighborEntities( entity ),
         BaseType( entity ) 
       {}
             
@@ -45,51 +45,51 @@ class tnlTestNeighbourGridEntityLayer
                     const typename GridEntity::GridType::IndexType& entityIndex )
       {
          BaseType::refresh( grid, entityIndex );
-         neighbourEntities.refresh( grid, entityIndex );
+         neighborEntities.refresh( grid, entityIndex );
       };
       
    protected:
       
-      NeighbourEntityGetterType neighbourEntities;
+      NeighborEntityGetterType neighborEntities;
 };
 
 template< typename GridEntity >
-class tnlTestNeighbourGridEntityLayer< GridEntity, 0 >
+class tnlTestNeighborGridEntityLayer< GridEntity, 0 >
 {
    public:
       
-      typedef tnlTestNeighbourGridEntityGetter< GridEntity, 0 > NeighbourEntityGetterType;     
+      typedef tnlTestNeighborGridEntityGetter< GridEntity, 0 > NeighborEntityGetterType;     
       
       __cuda_callable__
-      tnlTestNeighbourGridEntityLayer( const GridEntity& entity )
-      : neighbourEntities( entity )
+      tnlTestNeighborGridEntityLayer( const GridEntity& entity )
+      : neighborEntities( entity )
       {}
       
       __cuda_callable__
       void refresh( const typename GridEntity::GridType& grid, 
                     const typename GridEntity::GridType::IndexType& entityIndex )
       {
-         neighbourEntities.refresh( grid, entityIndex );
+         neighborEntities.refresh( grid, entityIndex );
       };
       
    protected:
       
-      NeighbourEntityGetterType neighbourEntities;
+      NeighborEntityGetterType neighborEntities;
    
 };
 
 template< typename GridEntity >
-class tnlTestNeighbourGridEntitiesStorage
-: public tnlTestNeighbourGridEntityLayer< GridEntity, GridEntity::meshDimensions >
+class tnlTestNeighborGridEntitiesStorage
+: public tnlTestNeighborGridEntityLayer< GridEntity, GridEntity::meshDimension >
 {
-   typedef tnlTestNeighbourGridEntityLayer< GridEntity, GridEntity::meshDimensions > BaseType;
+   typedef tnlTestNeighborGridEntityLayer< GridEntity, GridEntity::meshDimension > BaseType;
    
    public:
       
-      using BaseType::getNeighbourEntities;
+      using BaseType::getNeighborEntities;
       
       __cuda_callable__
-      tnlTestNeighbourGridEntitiesStorage( const GridEntity& entity )
+      tnlTestNeighborGridEntitiesStorage( const GridEntity& entity )
       : BaseType( entity )
       {}
 
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter.h b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter.h
index 29635a441122b9e457f60e8207ba857282d7e56b..521c58ff56902084a602e33bf131808e33d54862 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnlTestNeighbourGridEntityGetter.h  -  description
+                          tnlTestNeighborGridEntityGetter.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -17,30 +17,30 @@
 
 #pragma once 
 
-#include <core/tnlAssert.h>
+#include <core/tnlTNL_ASSERT.h>
 
 
 template< typename GridEntity,
-          int NeighbourEntityDimensions,
+          int NeighborEntityDimension,
           typename EntityStencilTag = 
-            GridEntityStencilStorageTag< GridEntity::ConfigType::template neighbourEntityStorage< GridEntity >( NeighbourEntityDimensions ) > >
-class tnlTestNeighbourGridEntityGetter
+            GridEntityStencilStorageTag< GridEntity::ConfigType::template neighborEntityStorage< GridEntity >( NeighborEntityDimension ) > >
+class tnlTestNeighborGridEntityGetter
 {
    public:
 
       // TODO: not all specializations are implemented yet
       
       __cuda_callable__
-      tnlTestNeighbourGridEntityGetter( const GridEntity& entity )
+      tnlTestNeighborGridEntityGetter( const GridEntity& entity )
       {
-         //tnlAssert( false, );
+         //tnlTNL_ASSERT( false, );
       };
       
       __cuda_callable__
       void refresh( const typename GridEntity::GridType& grid,
                     const typename GridEntity::IndexType& entityIndex )
       {
-         //tnlAssert( false, );
+         //tnlTNL_ASSERT( false, );
       };
 
 };
@@ -50,25 +50,25 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class tnlTestNeighbourGridEntityGetter< 
+class tnlTestNeighborGridEntityGetter< 
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    2,
    StencilStorage >
 {
    public:
       
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetter;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetter;
 
       __cuda_callable__ inline
-      tnlTestNeighbourGridEntityGetter( const GridEntityType& entity )
+      tnlTestNeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
             
@@ -79,7 +79,7 @@ class tnlTestNeighbourGridEntityGetter<
 
       const GridEntityType& entity;
       
-      //tnlTestNeighbourGridEntityGetter(){};      
+      //tnlTestNeighborGridEntityGetter(){};      
 };
 
 
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter2D_impl.h b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter2D_impl.h
index b3a0f6df44a8fb1aa2aa435444f8910fff563685..23d35fdae1038c6ec82e65fd69febfb1b0c6779a 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter2D_impl.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestNeighbourGridEntityGetter2D_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnlTestNeighbourGridEntityGetter2D_impl.h  -  description
+                          tnlTestNeighborGridEntityGetter2D_impl.h  -  description
                              -------------------
     begin                : Nov 23, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -17,13 +17,13 @@
 
 #pragma once
 
-#include "tnlTestNeighbourGridEntityGetter.h"
+#include "tnlTestNeighborGridEntityGetter.h"
 #include <mesh/grids/Grid2D.h>
 #include <core/tnlStaticFor.h>
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              2            | No specialization |
  * +-----------------+---------------------------+-------------------+
@@ -33,25 +33,25 @@ template< typename Real,
           typename Index,
           typename Config,
           typename StencilStorage >
-class tnlTestNeighbourGridEntityGetter< 
+class tnlTestNeighborGridEntityGetter< 
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    2,
    StencilStorage >
 {
    public:
       
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetter;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetter;
 
       __cuda_callable__ inline
-      tnlTestNeighbourGridEntityGetter( const GridEntityType& entity )
+      tnlTestNeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
             
@@ -62,12 +62,12 @@ class tnlTestNeighbourGridEntityGetter<
 
       const GridEntityType& entity;
       
-      //tnlTestNeighbourGridEntityGetter(){};      
+      //tnlTestNeighborGridEntityGetter(){};      
 };
 
 /****
  * +-----------------+---------------------------+-------------------+
- * | EntityDimenions | NeighbourEntityDimensions |  Stencil Storage  |
+ * | EntityDimenions | NeighborEntityDimension |  Stencil Storage  |
  * +-----------------+---------------------------+-------------------+
  * |       2         |              2            |       Cross       |
  * +-----------------+---------------------------+-------------------+
@@ -76,30 +76,30 @@ template< typename Real,
           typename Device,
           typename Index,
           typename Config >
-class tnlTestNeighbourGridEntityGetter< 
+class tnlTestNeighborGridEntityGetter< 
    GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >,
    2,
    GridEntityStencilStorageTag< GridEntityCrossStencil > >
 {
    public:
       
-      static const int EntityDimensions = 2;
-      static const int NeighbourEntityDimensions = 2;
+      static const int EntityDimension = 2;
+      static const int NeighborEntityDimension = 2;
       typedef Meshes::Grid< 2, Real, Device, Index > GridType;
-      typedef GridEntity< GridType, EntityDimensions, Config > GridEntityType;
-      typedef GridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef GridEntity< GridType, EntityDimension, Config > GridEntityType;
+      typedef GridEntity< GridType, NeighborEntityDimension, Config > NeighborGridEntityType;
       typedef Real RealType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
-      typedef GridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetter;
+      typedef GridEntityGetter< GridType, NeighborGridEntityType > GridEntityGetter;
       typedef GridEntityStencilStorageTag< GridEntityCrossStencil > StencilStorage;
-      typedef tnlTestNeighbourGridEntityGetter< GridEntityType, 2, StencilStorage > ThisType;
+      typedef tnlTestNeighborGridEntityGetter< GridEntityType, 2, StencilStorage > ThisType;
       
       
       static const int stencilSize = Config::getStencilSize();
 
       __cuda_callable__ inline
-      tnlTestNeighbourGridEntityGetter( const GridEntityType& entity )
+      tnlTestNeighborGridEntityGetter( const GridEntityType& entity )
       : entity( entity )
       {}
       
@@ -110,9 +110,9 @@ class tnlTestNeighbourGridEntityGetter<
          public:
             
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
+               neighborEntityGetter.stencilX[ index + stencilSize ] = entityIndex + index;
             }
       };
 
@@ -122,10 +122,10 @@ class tnlTestNeighbourGridEntityGetter<
          public:
             
             __cuda_callable__
-            static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
+            static void exec( ThisType& neighborEntityGetter, const IndexType& entityIndex )
             {
-               neighbourEntityGetter.stencilY[ index + stencilSize ] = 
-                  entityIndex + index * neighbourEntityGetter.entity.getMesh().getDimensions().x();
+               neighborEntityGetter.stencilY[ index + stencilSize ] = 
+                  entityIndex + index * neighborEntityGetter.entity.getMesh().getDimensions().x();
             }
       };
 
@@ -134,9 +134,9 @@ class tnlTestNeighbourGridEntityGetter<
       void refresh( const GridType& grid, const IndexType& entityIndex )
       {
 #ifndef HAVE_CUDA // TODO: fix this to work with CUDA
-         tnlStaticFor< IndexType, -stencilSize, 0, StencilYRefresher >::exec( *this, entityIndex );
-         tnlStaticFor< IndexType, 1, stencilSize + 1, StencilYRefresher >::exec( *this, entityIndex );
-         tnlStaticFor< IndexType, -stencilSize, stencilSize + 1, StencilXRefresher >::exec( *this, entityIndex );
+         StaticFor< IndexType, -stencilSize, 0, StencilYRefresher >::exec( *this, entityIndex );
+         StaticFor< IndexType, 1, stencilSize + 1, StencilYRefresher >::exec( *this, entityIndex );
+         StaticFor< IndexType, -stencilSize, stencilSize + 1, StencilXRefresher >::exec( *this, entityIndex );
 #endif
       };
       
@@ -147,6 +147,6 @@ class tnlTestNeighbourGridEntityGetter<
       IndexType stencilX[ 2 * stencilSize + 1 ];
       IndexType stencilY[ 2 * stencilSize + 1 ];
       
-      //tnlTestNeighbourGridEntityGetter(){};      
+      //tnlTestNeighborGridEntityGetter(){};      
 };
 
diff --git a/tests/benchmarks/share/CMakeLists.txt b/tests/benchmarks/share/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/benchmarks/spmv.h b/tests/benchmarks/spmv.h
index a197a15a73a0df9d2096dd6fc866b0a2b51e7036..c04a62eabe58a1474d5b9c8a2c361911d8762693 100644
--- a/tests/benchmarks/spmv.h
+++ b/tests/benchmarks/spmv.h
@@ -1,8 +1,20 @@
+/***************************************************************************
+                          spmv.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
 #include "benchmarks.h"
 
-#include <TNL/List.h>
+#include <TNL/Containers/List.h>
 #include <TNL/Matrices/CSR.h>
 #include <TNL/Matrices/Ellpack.h>
 #include <TNL/Matrices/SlicedEllpack.h>
@@ -72,7 +84,7 @@ void setCudaTestMatrix( Matrix& matrix,
         setCudaTestMatrixKernel< Matrix >
             <<< cudaGridSize, cudaBlockSize >>>
             ( kernel_matrix, elementsPerRow, gridIdx );
-        checkCudaDevice;
+        TNL_CHECK_CUDA_DEVICE;
     }
     Devices::Cuda::freeFromDevice( kernel_matrix );
 #endif
@@ -102,40 +114,30 @@ benchmarkSpMV( Benchmark & benchmark,
     CudaVector deviceVector, deviceVector2;
 
     // create benchmark group
-    List< String > parsedType;
+    Containers::List< String > 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";
-        std::cerr << msg << std::endl;
-        benchmark.addErrorMessage( msg, 2 );
-        return false;
-    }
+    hostRowLengths.setSize( size );
+    hostMatrix.setDimensions( size, size );
+    hostVector.setSize( size );
+    hostVector2.setSize( size );
+#ifdef HAVE_CUDA
+    deviceRowLengths.setSize( size );
+    deviceMatrix.setDimensions( size, size );
+    deviceVector.setSize( size );
+    deviceVector2.setSize( size );
+#endif
 
     hostRowLengths.setValue( elementsPerRow );
+#ifdef HAVE_CUDA
     deviceRowLengths.setValue( elementsPerRow );
+#endif
 
-    if( ! hostMatrix.setCompressedRowsLengths( hostRowLengths ) ) {
-        const char* msg = "error: allocation of host matrix failed";
-        std::cerr << msg << std::endl;
-        benchmark.addErrorMessage( msg, 2 );
-        return false;
-    }
-    if( ! deviceMatrix.setCompressedRowsLengths( deviceRowLengths ) ) {
-        const char* msg = "error: allocation of device matrix failed";
-        std::cerr << msg << std::endl;
-        benchmark.addErrorMessage( msg, 2 );
-        return false;
-    }
+    hostMatrix.setCompressedRowLengths( hostRowLengths );
+#ifdef HAVE_CUDA
+    deviceMatrix.setCompressedRowLengths( deviceRowLengths );
+#endif
 
     const int elements = setHostTestMatrix< HostMatrix >( hostMatrix, elementsPerRow );
     setCudaTestMatrix< DeviceMatrix >( deviceMatrix, elementsPerRow );
@@ -144,9 +146,11 @@ benchmarkSpMV( Benchmark & benchmark,
     // reset function
     auto reset = [&]() {
         hostVector.setValue( 1.0 );
-        deviceVector.setValue( 1.0 );
         hostVector2.setValue( 0.0 );
+#ifdef HAVE_CUDA
+        deviceVector.setValue( 1.0 );
         deviceVector2.setValue( 0.0 );
+#endif
     };
 
     // compute functions
@@ -158,9 +162,10 @@ benchmarkSpMV( Benchmark & benchmark,
     };
 
     benchmark.setOperation( datasetSize );
-    benchmark.time( reset,
-                    "CPU", spmvHost,
-                    "GPU", spmvCuda );
+    benchmark.time( reset, "CPU", spmvHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset, "GPU", spmvCuda );
+#endif
 
     return true;
 }
diff --git a/tests/benchmarks/tnl-cuda-benchmarks.cu b/tests/benchmarks/tnl-benchmark-blas.cpp
similarity index 80%
rename from tests/benchmarks/tnl-cuda-benchmarks.cu
rename to tests/benchmarks/tnl-benchmark-blas.cpp
index b92e8d52a59f5ad62714464917b8dbdb19624d7e..76ec0448a74f84d76e78ef6237cc44736d015abf 100644
--- a/tests/benchmarks/tnl-cuda-benchmarks.cu
+++ b/tests/benchmarks/tnl-benchmark-blas.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          tnl-cuda-benchmarks.cu  -  description
+                          tnl-benchmark-blas.cpp  -  description
                              -------------------
     begin                : May 28, 2015
     copyright            : (C) 2015 by Tomas Oberhuber
@@ -8,4 +8,4 @@
 
 /* See Copyright Notice in tnl/Copyright */
 
-#include "tnl-cuda-benchmarks.h"
+#include "tnl-benchmark-blas.h"
diff --git a/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.cpp b/tests/benchmarks/tnl-benchmark-blas.cu
similarity index 61%
rename from src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.cpp
rename to tests/benchmarks/tnl-benchmark-blas.cu
index ebce329454f166df941c143237f173d801ffe697..f35d5a5f5b6de701687adb51b5bd52e8b6b0c1f5 100644
--- a/src/TNL/Containers/Algorithms/cuda-prefix-sum_impl.cpp
+++ b/tests/benchmarks/tnl-benchmark-blas.cu
@@ -1,13 +1,11 @@
 /***************************************************************************
-                          cuda-prefix-sum_impl.cpp  -  description
+                          tnl-benchmark-blas.cu  -  description
                              -------------------
-    begin                : Jan 18, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
+    begin                : May 28, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
 /* See Copyright Notice in tnl/Copyright */
 
-
-
-
+#include "tnl-benchmark-blas.h"
diff --git a/tests/benchmarks/tnl-cuda-benchmarks.h b/tests/benchmarks/tnl-benchmark-blas.h
similarity index 73%
rename from tests/benchmarks/tnl-cuda-benchmarks.h
rename to tests/benchmarks/tnl-benchmark-blas.h
index 1b0aba5303b3eb8f7dd7fd16f0f054c12421332b..ecf9b08c65d8c36b47d51dff4c062b1c45cd8b45 100644
--- a/tests/benchmarks/tnl-cuda-benchmarks.h
+++ b/tests/benchmarks/tnl-benchmark-blas.h
@@ -1,17 +1,18 @@
 /***************************************************************************
-                          tnl-benchmarks.h  -  description
+                          tnl-benchmark-blas.h  -  description
                              -------------------
     begin                : Jan 27, 2010
-    copyright            : (C) 2010 by Tomas Oberhuber
+    copyright            : (C) 2010 by Tomas Oberhuber et al.
     email                : tomas.oberhuber@fjfi.cvut.cz
  ***************************************************************************/
 
 /* See Copyright Notice in tnl/Copyright */
 
-#ifndef tnlCudaBENCHMARKS_H_
-#define TNLCUDBENCHMARKS_H_
+// Implemented by: Jakub Klinkovsky
 
-#include <TNL/SystemInfo.h>
+#pragma once
+
+#include <TNL/Devices/Host.h>
 #include <TNL/Devices/CudaDeviceInfo.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Config/ParameterContainer.h>
@@ -29,10 +30,10 @@ using namespace TNL::benchmarks;
 
 template< typename Real >
 void
-runCudaBenchmarks( Benchmark & benchmark,
+runBlasBenchmarks( Benchmark & benchmark,
                    Benchmark::MetadataMap metadata,
-                   const unsigned & minSize,
-                   const unsigned & maxSize,
+                   const std::size_t & minSize,
+                   const std::size_t & maxSize,
                    const double & sizeStepFactor,
                    const unsigned & loops,
                    const unsigned & elementsPerRow )
@@ -43,7 +44,7 @@ runCudaBenchmarks( Benchmark & benchmark,
     // Array operations
     benchmark.newBenchmark( String("Array operations (") + precision + ")",
                             metadata );
-    for( unsigned size = minSize; size <= maxSize; size *= 2 ) {
+    for( std::size_t size = minSize; size <= maxSize; size *= 2 ) {
         benchmark.setMetadataColumns( Benchmark::MetadataColumns({
            {"size", size},
         } ));
@@ -53,7 +54,7 @@ runCudaBenchmarks( Benchmark & benchmark,
     // Vector operations
     benchmark.newBenchmark( String("Vector operations (") + precision + ")",
                             metadata );
-    for( unsigned size = minSize; size <= maxSize; size *= sizeStepFactor ) {
+    for( std::size_t size = minSize; size <= maxSize; size *= sizeStepFactor ) {
         benchmark.setMetadataColumns( Benchmark::MetadataColumns({
            {"size", size},
         } ));
@@ -63,7 +64,7 @@ runCudaBenchmarks( Benchmark & benchmark,
     // Sparse matrix-vector multiplication
     benchmark.newBenchmark( String("Sparse matrix-vector multiplication (") + precision + ")",
                             metadata );
-    for( unsigned size = minSize; size <= maxSize; size *= 2 ) {
+    for( std::size_t size = minSize; size <= maxSize; size *= 2 ) {
         benchmark.setMetadataColumns( Benchmark::MetadataColumns({
             {"rows", size},
             {"columns", size},
@@ -77,7 +78,7 @@ void
 setupConfig( Config::ConfigDescription & config )
 {
     config.addDelimiter( "Benchmark settings:" );
-    config.addEntry< String >( "log-file", "Log file name.", "tnl-cuda-benchmarks.log");
+    config.addEntry< String >( "log-file", "Log file name.", "tnl-benchmark-blas.log");
     config.addEntry< String >( "output-mode", "Mode for opening the log file.", "overwrite" );
     config.addEntryEnum( "append" );
     config.addEntryEnum( "overwrite" );
@@ -91,12 +92,15 @@ setupConfig( Config::ConfigDescription & config )
     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 );
+
+    config.addDelimiter( "Device settings:" );
+    Devices::Host::configSetup( config );
+    Devices::Cuda::configSetup( config );
 }
 
 int
 main( int argc, char* argv[] )
 {
-#ifdef HAVE_CUDA
     Config::ParameterContainer parameters;
     Config::ConfigDescription conf_desc;
 
@@ -107,11 +111,19 @@ main( int argc, char* argv[] )
         return 1;
     }
 
+    Devices::Host::setup( parameters );
+    Devices::Cuda::setup( parameters );
+
     const String & logFileName = parameters.getParameter< String >( "log-file" );
     const String & outputMode = parameters.getParameter< String >( "output-mode" );
     const String & precision = parameters.getParameter< String >( "precision" );
-    const unsigned minSize = parameters.getParameter< unsigned >( "min-size" );
-    const unsigned maxSize = parameters.getParameter< unsigned >( "max-size" );
+    // FIXME: getParameter< std::size_t >() does not work with parameters added with addEntry< int >(),
+    // which have a default value. The workaround below works for int values, but it is not possible
+    // to pass 64-bit integer values
+//    const std::size_t minSize = parameters.getParameter< std::size_t >( "min-size" );
+//    const std::size_t maxSize = parameters.getParameter< std::size_t >( "max-size" );
+    const std::size_t minSize = parameters.getParameter< int >( "min-size" );
+    const std::size_t maxSize = parameters.getParameter< int >( "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" );
@@ -132,27 +144,29 @@ main( int argc, char* argv[] )
     Benchmark benchmark( loops, verbose );
 
     // prepare global metadata
-    SystemInfo systemInfo;
     const int cpu_id = 0;
-    tnlCacheSizes cacheSizes = systemInfo.getCPUCacheSizes( cpu_id );
+    Devices::CacheSizes cacheSizes = Devices::Host::getCPUCacheSizes( cpu_id );
     String cacheInfo = String( cacheSizes.L1data ) + ", "
                         + String( cacheSizes.L1instruction ) + ", "
                         + String( cacheSizes.L2 ) + ", "
                         + String( cacheSizes.L3 );
+#ifdef HAVE_CUDA
     const int activeGPU = Devices::CudaDeviceInfo::getActiveDevice();
     const String deviceArch = String( Devices::CudaDeviceInfo::getArchitectureMajor( activeGPU ) ) + "." +
-                                 String( Devices::CudaDeviceInfo::getArchitectureMinor( activeGPU ) );
+                              String( Devices::CudaDeviceInfo::getArchitectureMinor( activeGPU ) );
+#endif
     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 },
+        { "host name", Devices::Host::getHostname() },
+        { "architecture", Devices::Host::getArchitecture() },
+        { "system", Devices::Host::getSystemName() },
+        { "system release", Devices::Host::getSystemRelease() },
+        { "start time", Devices::Host::getCurrentTime() },
+        { "CPU model name", Devices::Host::getCPUModelName( cpu_id ) },
+        { "CPU cores", Devices::Host::getNumberOfCores( cpu_id ) },
+        { "CPU threads per core", Devices::Host::getNumberOfThreads( cpu_id ) / Devices::Host::getNumberOfCores( cpu_id ) },
+        { "CPU max frequency (MHz)", Devices::Host::getCPUMaxFrequency( cpu_id ) / 1e3 },
         { "CPU cache sizes (L1d, L1i, L2, L3) (kiB)", cacheInfo },
+#ifdef HAVE_CUDA
         { "GPU name", Devices::CudaDeviceInfo::getDeviceName( activeGPU ) },
         { "GPU architecture", deviceArch },
         { "GPU CUDA cores", Devices::CudaDeviceInfo::getCudaCores( activeGPU ) },
@@ -160,12 +174,13 @@ main( int argc, char* argv[] )
         { "GPU global memory (GB)", (double) Devices::CudaDeviceInfo::getGlobalMemory( activeGPU ) / 1e9 },
         { "GPU memory clock rate (MHz)", (double) Devices::CudaDeviceInfo::getMemoryClockRate( activeGPU ) / 1e3 },
         { "GPU memory ECC enabled", Devices::CudaDeviceInfo::getECCEnabled( activeGPU ) },
+#endif
     };
 
     if( precision == "all" || precision == "float" )
-        runCudaBenchmarks< float >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
+        runBlasBenchmarks< float >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
     if( precision == "all" || precision == "double" )
-        runCudaBenchmarks< double >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
+        runBlasBenchmarks< double >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
 
     if( ! benchmark.save( logFile ) ) {
         std::cerr << "Failed to write the benchmark results to file '" << parameters.getParameter< String >( "log-file" ) << "'." << std::endl;
@@ -173,10 +188,4 @@ main( int argc, char* argv[] )
     }
 
     return EXIT_SUCCESS;
-#else
-    CudaSupportMissingMessage;
-    return EXIT_FAILURE;
-#endif
 }
-
-#endif /* Devices::CudaBENCHMARKS_H_ */
diff --git a/tests/benchmarks/tnl-benchmark-spmv.h b/tests/benchmarks/tnl-benchmark-spmv.h
index 3fcb997c3f4d0711ca43d847b61aa8be89f7c1de..a7ebf68dc40e368929f7a5c284e65ead69845783 100644
--- a/tests/benchmarks/tnl-benchmark-spmv.h
+++ b/tests/benchmarks/tnl-benchmark-spmv.h
@@ -326,7 +326,6 @@ bool setupBenchmark( const Config::ParameterContainer& parameters )
          return false;
       }
       const int rows = csrMatrix.getRows();
-      const int columns = csrMatrix.getColumns();
       const long int nonzeroElements = csrMatrix.getNumberOfMatrixElements();
       Containers::Vector< int, Devices::Host, int > rowLengthsHost;
       rowLengthsHost.setSize( rows );
@@ -363,160 +362,153 @@ bool setupBenchmark( const Config::ParameterContainer& parameters )
       typedef CSR< Real, Devices::Cuda, int > CSRCudaType;
       CSRCudaType cudaCSR;
       //cout << "Copying matrix to GPU... ";
-      if( ! cudaCSR.copyFrom( csrMatrix, rowLengthsCuda ) )
-      {
-         std::cerr << "I am not able to transfer the matrix on GPU." << std::endl;
-         writeTestFailed( logFile, 21 );
-      }
-      else
-      {
-         ::tnlCusparseCSR< Real > cusparseCSR;
-         cusparseCSR.init( cudaCSR, &cusparseHandle );
-         benchmarkMatrix( cusparseCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "Cusparse CSR",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cusparseDestroy( cusparseHandle );
+      cudaCSR = csrMatrix;
+      ::tnlCusparseCSR< Real > cusparseCSR;
+      cusparseCSR.init( cudaCSR, &cusparseHandle );
+      benchmarkMatrix( cusparseCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "Cusparse CSR",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cusparseDestroy( cusparseHandle );
 
-        std::cout << " done.   \r";
-         /*cudaCSR.setCudaKernelType( CSRCudaType::scalar );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Scalar",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaKernelType( CSRCudaType::vector );
-         cudaCSR.setCudaWarpSize( 1 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 1",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaWarpSize( 2 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 2",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaWarpSize( 4 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 4",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaWarpSize( 8 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 8",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaWarpSize( 16 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 16",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaWarpSize( 32 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Vector 32",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setCudaKernelType( CSRCudaType::hybrid );
-         cudaCSR.setHybridModeSplit( 2 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 2",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setHybridModeSplit( 4 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 4",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setHybridModeSplit( 8 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 8",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setHybridModeSplit( 16 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 16",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setHybridModeSplit( 32 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 32",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
-         cudaCSR.setHybridModeSplit( 64 );
-         benchmarkMatrix( cudaCSR,
-                          cudaX,
-                          cudaB,
-                          nonzeroElements,
-                          "CSR Cuda Hyrbid 64",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );*/
-      }
+      std::cout << " done.   \r";
+      /*cudaCSR.setCudaKernelType( CSRCudaType::scalar );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Scalar",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaKernelType( CSRCudaType::vector );
+      cudaCSR.setCudaWarpSize( 1 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 1",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaWarpSize( 2 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 2",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaWarpSize( 4 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 4",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaWarpSize( 8 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 8",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaWarpSize( 16 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 16",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaWarpSize( 32 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Vector 32",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setCudaKernelType( CSRCudaType::hybrid );
+      cudaCSR.setHybridModeSplit( 2 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 2",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setHybridModeSplit( 4 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 4",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setHybridModeSplit( 8 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 8",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setHybridModeSplit( 16 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 16",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setHybridModeSplit( 32 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 32",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaCSR.setHybridModeSplit( 64 );
+      benchmarkMatrix( cudaCSR,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "CSR Cuda Hyrbid 64",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );*/
       cudaCSR.reset();
 #endif
 
@@ -524,138 +516,105 @@ bool setupBenchmark( const Config::ParameterContainer& parameters )
       double padding;
       typedef Ellpack< Real, Devices::Host, int > EllpackType;
       EllpackType ellpackMatrix;
-      if( ! ellpackMatrix.copyFrom( csrMatrix, rowLengthsHost ) )
-         writeTestFailed( logFile, 7 );
-      else
-      {
-         allocatedElements = ellpackMatrix.getNumberOfMatrixElements();
-         padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
-         logFile << "    " << padding << std::endl;
-         benchmarkMatrix( ellpackMatrix,
-                          hostX,
-                          hostB,
-                          nonzeroElements,
-                          "Ellpack Host",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
+      Matrices::copySparseMatrix( ellpackMatrix, csrMatrix );
+      allocatedElements = ellpackMatrix.getNumberOfMatrixElements();
+      padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
+      logFile << "    " << padding << std::endl;
+      benchmarkMatrix( ellpackMatrix,
+                       hostX,
+                       hostB,
+                       nonzeroElements,
+                       "Ellpack Host",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
 #ifdef HAVE_CUDA
-         typedef Ellpack< Real, Devices::Cuda, int > EllpackCudaType;
-         EllpackCudaType cudaEllpack;
-        std::cout << "Copying matrix to GPU... ";
-         if( ! cudaEllpack.copyFrom( ellpackMatrix, rowLengthsCuda ) )
-         {
-            std::cerr << "I am not able to transfer the matrix on GPU." << std::endl;
-            writeTestFailed( logFile, 3 );
-         }
-         else
-         {
-           std::cout << " done.   \r";
-            benchmarkMatrix( cudaEllpack,
-                             cudaX,
-                             cudaB,
-                             nonzeroElements,
-                             "Ellpack Cuda",
-                             stopTime,
-                             baseline,
-                             verbose,
-                             logFile );
-         }
-         cudaEllpack.reset();
+      typedef Ellpack< Real, Devices::Cuda, int > EllpackCudaType;
+      EllpackCudaType cudaEllpack;
+      std::cout << "Copying matrix to GPU... ";
+      cudaEllpack = ellpackMatrix;
+      std::cout << " done.   \r";
+      benchmarkMatrix( cudaEllpack,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "Ellpack Cuda",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaEllpack.reset();
 #endif
-         ellpackMatrix.reset();
-      }
+      ellpackMatrix.reset();
 
       typedef SlicedEllpack< Real, Devices::Host, int > SlicedEllpackType;
       SlicedEllpackType slicedEllpack;
-      if( ! slicedEllpack.copyFrom( csrMatrix, rowLengthsHost ) )
-         writeTestFailed( logFile, 7 );
-      else
-      {
-         allocatedElements = slicedEllpack.getNumberOfMatrixElements();
-         padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
-         logFile << "    " << padding << std::endl;
-         benchmarkMatrix( slicedEllpack,
-                          hostX,
-                          hostB,
-                          nonzeroElements,
-                          "SlicedEllpack Host",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
+      Matrices::copySparseMatrix( slicedEllpack, csrMatrix );
+      allocatedElements = slicedEllpack.getNumberOfMatrixElements();
+      padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
+      logFile << "    " << padding << std::endl;
+      benchmarkMatrix( slicedEllpack,
+                       hostX,
+                       hostB,
+                       nonzeroElements,
+                       "SlicedEllpack Host",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
 #ifdef HAVE_CUDA
-         typedef SlicedEllpack< Real, Devices::Cuda, int > SlicedEllpackCudaType;
-         SlicedEllpackCudaType cudaSlicedEllpack;
-        std::cout << "Copying matrix to GPU... ";
-         if( ! cudaSlicedEllpack.copyFrom( slicedEllpack, rowLengthsCuda ) )
-         {
-            std::cerr << "I am not able to transfer the matrix on GPU." << std::endl;
-            writeTestFailed( logFile, 3 );
-         }
-         else
-         {
-           std::cout << " done.   \r";
-            benchmarkMatrix( cudaSlicedEllpack,
-                             cudaX,
-                             cudaB,
-                             nonzeroElements,
-                             "SlicedEllpack Cuda",
-                             stopTime,
-                             baseline,
-                             verbose,
-                             logFile );
-         }
-         cudaSlicedEllpack.reset();
+      typedef SlicedEllpack< Real, Devices::Cuda, int > SlicedEllpackCudaType;
+      SlicedEllpackCudaType cudaSlicedEllpack;
+      std::cout << "Copying matrix to GPU... ";
+      cudaSlicedEllpack = slicedEllpack;
+      std::cout << " done.   \r";
+      benchmarkMatrix( cudaSlicedEllpack,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "SlicedEllpack Cuda",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaSlicedEllpack.reset();
 #endif
-         slicedEllpack.reset();
-      }
+      slicedEllpack.reset();
 
       typedef ChunkedEllpack< Real, Devices::Host, int > ChunkedEllpackType;
       ChunkedEllpackType chunkedEllpack;
-      if( ! chunkedEllpack.copyFrom( csrMatrix, rowLengthsHost ) )
-         writeTestFailed( logFile, 7 );
-      else
-      {
-         allocatedElements = chunkedEllpack.getNumberOfMatrixElements();
-         padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
-         logFile << "    " << padding << std::endl;
-         benchmarkMatrix( chunkedEllpack,
-                          hostX,
-                          hostB,
-                          nonzeroElements,
-                          "ChunkedEllpack Host",
-                          stopTime,
-                          baseline,
-                          verbose,
-                          logFile );
+      Matrices::copySparseMatrix( chunkedEllpack, csrMatrix );
+      allocatedElements = chunkedEllpack.getNumberOfMatrixElements();
+      padding = ( double ) allocatedElements / ( double ) nonzeroElements * 100.0 - 100.0;
+      logFile << "    " << padding << std::endl;
+      benchmarkMatrix( chunkedEllpack,
+                       hostX,
+                       hostB,
+                       nonzeroElements,
+                       "ChunkedEllpack Host",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
 #ifdef HAVE_CUDA
-         typedef ChunkedEllpack< Real, Devices::Cuda, int > ChunkedEllpackCudaType;
-         ChunkedEllpackCudaType cudaChunkedEllpack;
-        std::cout << "Copying matrix to GPU... ";
-         if( ! cudaChunkedEllpack.copyFrom( chunkedEllpack, rowLengthsCuda ) )
-         {
-            std::cerr << "I am not able to transfer the matrix on GPU." << std::endl;
-            writeTestFailed( logFile, 3 );
-         }
-         else
-         {
-           std::cout << " done.    \r";
-            benchmarkMatrix( cudaChunkedEllpack,
-                             cudaX,
-                             cudaB,
-                             nonzeroElements,
-                             "ChunkedEllpack Cuda",
-                             stopTime,
-                             baseline,
-                             verbose,
-                             logFile );
-         }
-         cudaChunkedEllpack.reset();
+      typedef ChunkedEllpack< Real, Devices::Cuda, int > ChunkedEllpackCudaType;
+      ChunkedEllpackCudaType cudaChunkedEllpack;
+      std::cout << "Copying matrix to GPU... ";
+      cudaChunkedEllpack = chunkedEllpack;
+      std::cout << " done.    \r";
+      benchmarkMatrix( cudaChunkedEllpack,
+                       cudaX,
+                       cudaB,
+                       nonzeroElements,
+                       "ChunkedEllpack Cuda",
+                       stopTime,
+                       baseline,
+                       verbose,
+                       logFile );
+      cudaChunkedEllpack.reset();
 #endif
-         chunkedEllpack.reset();
-      }
+      chunkedEllpack.reset();
    }
    return true;
 }
diff --git a/tests/benchmarks/tnlCusparseCSRMatrix.h b/tests/benchmarks/tnlCusparseCSRMatrix.h
index 85a67386cff105b3af75966bf74ada58d79d59d1..08192c70fceff0739ce75678595dcc86b49e286b 100644
--- a/tests/benchmarks/tnlCusparseCSRMatrix.h
+++ b/tests/benchmarks/tnlCusparseCSRMatrix.h
@@ -60,7 +60,7 @@ class tnlCusparseCSRBase
       void vectorProduct( const InVector& inVector,
                           OutVector& outVector ) const
       {
-         Assert( matrix, );
+         TNL_ASSERT( matrix, );
 #ifdef HAVE_CUDA
          cusparseDcsrmv( *( this->cusparseHandle ),
                          CUSPARSE_OPERATION_NON_TRANSPOSE,
@@ -103,7 +103,7 @@ class tnlCusparseCSR< double > : public tnlCusparseCSRBase< double >
       void vectorProduct( const InVector& inVector,
                           OutVector& outVector ) const
       {
-         Assert( matrix, );
+         TNL_ASSERT( matrix, );
 #ifdef HAVE_CUDA
          /*cusparseDcsrmv( *( this->cusparseHandle ),
                          CUSPARSE_OPERATION_NON_TRANSPOSE,
@@ -131,7 +131,7 @@ class tnlCusparseCSR< float > : public tnlCusparseCSRBase< float >
       void vectorProduct( const InVector& inVector,
                           OutVector& outVector ) const
       {
-         Assert( matrix, );
+         TNL_ASSERT( matrix, );
 #ifdef HAVE_CUDA
          /*cusparseScsrmv( *( this->cusparseHandle ),
                          CUSPARSE_OPERATION_NON_TRANSPOSE,
diff --git a/tests/benchmarks/vector-operations.h b/tests/benchmarks/vector-operations.h
index 4d0a7e00971d3aae415917888222c586fed48912..093243c07c1912919c0cd5baae1c0abb9f4a22b4 100644
--- a/tests/benchmarks/vector-operations.h
+++ b/tests/benchmarks/vector-operations.h
@@ -1,5 +1,19 @@
+/***************************************************************************
+                          vector-operations.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub Klinkovsky
+
 #pragma once
 
+#include <stdlib.h> // srand48
+
 #include "benchmarks.h"
 
 #include <TNL/Containers/Vector.h>
@@ -18,7 +32,7 @@ template< typename Real = double,
 bool
 benchmarkVectorOperations( Benchmark & benchmark,
                            const int & loops,
-                           const int & size )
+                           const long & size )
 {
     typedef Containers::Vector< Real, Devices::Host, Index > HostVector;
     typedef Containers::Vector< Real, Devices::Cuda, Index > CudaVector;
@@ -28,16 +42,12 @@ benchmarkVectorOperations( Benchmark & benchmark,
 
     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";
-        std::cerr << msg << std::endl;
-        benchmark.addErrorMessage( msg );
-        return false;
-    }
+    hostVector.setSize( size );
+    hostVector2.setSize( size );
+#ifdef HAVE_CUDA
+    deviceVector.setSize( size );
+    deviceVector2.setSize( size );
+#endif
 
     Real resultHost, resultDevice;
 
@@ -53,12 +63,19 @@ benchmarkVectorOperations( Benchmark & benchmark,
     // of the benchmark loop.)
     auto reset1 = [&]() {
         hostVector.setValue( 1.0 );
+#ifdef HAVE_CUDA
         deviceVector.setValue( 1.0 );
+#endif
+        // A relatively harmless call to keep the compiler from realizing we
+        // don't actually do any useful work with the result of the reduciton.
+        srand48(resultHost);
         resultHost = resultDevice = 0.0;
     };
     auto reset2 = [&]() {
         hostVector2.setValue( 1.0 );
+#ifdef HAVE_CUDA
         deviceVector2.setValue( 1.0 );
+#endif
     };
     auto reset12 = [&]() {
         reset1();
@@ -84,12 +101,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "scalar multiplication", 2 * datasetSize );
-    benchmark.time( reset1,
-                    "CPU", multiplyHost,
-                    "GPU", multiplyCuda );
+    benchmark.time( reset1, "CPU", multiplyHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", multiplyCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", multiplyCublas );
 #endif
+#endif
 
 
     auto addVectorHost = [&]() {
@@ -108,12 +126,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "vector addition", 3 * datasetSize );
-    benchmark.time( reset1,
-                    "CPU", addVectorHost,
-                    "GPU", addVectorCuda );
+    benchmark.time( reset1, "CPU", addVectorHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", addVectorCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", addVectorCublas );
 #endif
+#endif
 
 
     auto maxHost = [&]() {
@@ -123,9 +142,10 @@ benchmarkVectorOperations( Benchmark & benchmark,
         resultDevice = deviceVector.max();
     };
     benchmark.setOperation( "max", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", maxHost,
-                    "GPU", maxCuda );
+    benchmark.time( reset1, "CPU", maxHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", maxCuda );
+#endif
 
 
     auto minHost = [&]() {
@@ -135,9 +155,10 @@ benchmarkVectorOperations( Benchmark & benchmark,
         resultDevice = deviceVector.min();
     };
     benchmark.setOperation( "min", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", minHost,
-                    "GPU", minCuda );
+    benchmark.time( reset1, "CPU", minHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", minCuda );
+#endif
 
 
     auto absMaxHost = [&]() {
@@ -156,12 +177,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "absMax", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", absMaxHost,
-                    "GPU", absMaxCuda );
+    benchmark.time( reset1, "CPU", absMaxHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", absMaxCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", absMaxCublas );
 #endif
+#endif
 
 
     auto absMinHost = [&]() {
@@ -180,12 +202,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "absMin", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", absMinHost,
-                    "GPU", absMinCuda );
+    benchmark.time( reset1, "CPU", absMinHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", absMinCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", absMinCublas );
 #endif
+#endif
 
 
     auto sumHost = [&]() {
@@ -195,9 +218,10 @@ benchmarkVectorOperations( Benchmark & benchmark,
         resultDevice = deviceVector.sum();
     };
     benchmark.setOperation( "sum", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", sumHost,
-                    "GPU", sumCuda );
+    benchmark.time( reset1, "CPU", sumHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", sumCuda );
+#endif
 
 
     auto l1normHost = [&]() {
@@ -214,12 +238,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "l1 norm", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", l1normHost,
-                    "GPU", l1normCuda );
+    benchmark.time( reset1, "CPU", l1normHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", l1normCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", l1normCublas );
 #endif
+#endif
 
 
     auto l2normHost = [&]() {
@@ -236,12 +261,13 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "l2 norm", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", l2normHost,
-                    "GPU", l2normCuda );
+    benchmark.time( reset1, "CPU", l2normHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", l2normCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", l2normCublas );
 #endif
+#endif
 
 
     auto l3normHost = [&]() {
@@ -251,9 +277,10 @@ benchmarkVectorOperations( Benchmark & benchmark,
         resultDevice = deviceVector.lpNorm( 3.0 );
     };
     benchmark.setOperation( "l3 norm", datasetSize );
-    benchmark.time( reset1,
-                    "CPU", l3normHost,
-                    "GPU", l3normCuda );
+    benchmark.time( reset1, "CPU", l3normHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", l3normCuda );
+#endif
 
 
     auto scalarProductHost = [&]() {
@@ -271,11 +298,12 @@ benchmarkVectorOperations( Benchmark & benchmark,
     };
 #endif
     benchmark.setOperation( "scalar product", 2 * datasetSize );
-    benchmark.time( reset1,
-                    "CPU", scalarProductHost,
-                    "GPU", scalarProductCuda );
+    benchmark.time( reset1, "CPU", scalarProductHost );
+#ifdef HAVE_CUDA
+    benchmark.time( reset1, "GPU", scalarProductCuda );
 #ifdef HAVE_CUBLAS
     benchmark.time( reset1, "cuBLAS", scalarProductCublas );
+#endif
 #endif
 
     /*
diff --git a/tests/long-time-unit-tests/CMakeLists.txt b/tests/long-time-unit-tests/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/mic/CMakeLists.txt b/tests/mic/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e6d9e53437394174a3af73c6c63067a1633b229
--- /dev/null
+++ b/tests/mic/CMakeLists.txt
@@ -0,0 +1,9 @@
+    ADD_EXECUTABLE( tnlMICArrayTest${mpiExt}${debugExt} ${headers} tnlMICArrayTest.cpp )   
+    TARGET_LINK_LIBRARIES( tnlMICArrayTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                           tnl${mpiExt}${debugExt}-0.1 )
+    TARGET_COMPILE_DEFINITIONS( tnlMICArrayTest${mpiExt}${debugExt} PUBLIC ${MIC_CXX_FLAGS} )
+
+    ADD_EXECUTABLE( tnlMICVectorTest${mpiExt}${debugExt} ${headers} tnlMICVectorTest.cpp )   
+    TARGET_LINK_LIBRARIES( tnlMICVectorTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                           tnl${mpiExt}${debugExt}-0.1 )
+    TARGET_COMPILE_DEFINITIONS( tnlMICVectorTest${mpiExt}${debugExt} PUBLIC ${MIC_CXX_FLAGS} )
\ No newline at end of file
diff --git a/tests/mic/tnlMICArrayTest.cpp b/tests/mic/tnlMICArrayTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c932fad62a86d9ffc0b42abdb5494a954940a5c
--- /dev/null
+++ b/tests/mic/tnlMICArrayTest.cpp
@@ -0,0 +1,205 @@
+/***************************************************************************
+                          tnlMICArrayTest.cpp  -  
+                application testing Array implemntation on MIC KNC
+                              by hanouvit 
+                             -------------------
+    copyright            : (C) 2004 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+ 
+#include <iostream>
+#include <TNL/Devices/MIC.h>
+#include <omp.h>
+#include <TNL/Containers/Array.h>
+
+	using namespace std;
+	using namespace TNL;
+	using namespace TNL::Containers;
+
+//TUNE MACROS FOR YOUR FUNKY OUTPUT
+#define TEST_VERBOSE
+
+unsigned int errors=0;
+unsigned int success=0;
+#define TEST_TEST(a) if((a)){cout << __LINE__ <<":\t OK " <<endl;success++;}else{cout << __LINE__<<":\t FAIL" <<endl;errors++;}
+#define TEST_RESULT cout<<"SUCCES: "<<success<<endl<<"ERRRORS: "<<errors<<endl;
+inline void Test_Say( const char * message)
+{
+#ifdef TEST_VERBOSE
+	cout << message <<endl;
+#endif
+}
+
+using namespace std;
+
+
+int main(void)
+{
+    cout << "Array on MIC test by hanouvit:" <<endl;
+	
+	#ifdef HAVE_ICPC
+		cout << "ICPC in USE" <<endl;
+	#endif
+
+	#ifdef HAVE_MIC
+		cout << "MIC in USE" <<endl; //LOL
+	#endif
+	
+#ifdef HAVE_MIC
+//prepare arrays with data
+	
+	Array<double,Devices::MIC,int> aa(10);
+	Array<double,Devices::MIC,int> ee(6);
+	Array<double,Devices::Host,int> cc(5);
+
+//fill it 
+Devices::MICHider<double> data_ptr;
+data_ptr.pointer= aa.getData();	
+int size=aa.getSize();
+        
+#pragma offload target(mic) in(data_ptr,size)
+{
+    for(int i=0;i<size;i++)
+    {
+            data_ptr.pointer[i]=i;
+    }
+}
+
+for(int i=0;i<5;i++)
+{
+	cc[i]=10+i;
+}
+
+//prepare arrays for funky tests
+Array<double,Devices::MIC,int> bb(10);
+Array<double,Devices::MIC,int> dd(0);
+
+//TEST IT!
+Test_Say("aa.getSize():");
+TEST_TEST(aa.getSize()==10);
+
+Test_Say("Is aa filled correctly? (aa.getElement):");
+for(int i=0;i<10;i++)
+	TEST_TEST(aa.getElement(i)==i);
+
+Test_Say("Copy to bb(MIC->MIC) (=):");
+bb=aa;
+TEST_TEST(aa.getSize()==bb.getSize());
+for(int i=0;i<bb.getSize();i++)
+	TEST_TEST(bb.getElement(i)==i);
+
+Test_Say("setLike:");
+bb.setLike(cc);
+TEST_TEST(bb.getSize()==cc.getSize());
+Test_Say("Copy (Host -> MIC) (=)");
+bb=cc;
+for(int i=0;i<bb.getSize();i++)
+	TEST_TEST(bb.getElement(i)==i+10);
+
+Test_Say("setValue:");
+bb.setValue(5);
+for(int i=0;i<bb.getSize();i++)
+	TEST_TEST(bb.getElement(i)==5);
+
+Test_Say("swap:");
+aa.swap(bb);
+TEST_TEST(aa.getSize()==5||bb.getSize()==10);
+for(int i=0;i<aa.getSize();i++)
+{
+	TEST_TEST(aa.getElement(i)==5);
+}
+for(int i=0;i<bb.getSize();i++)
+{
+	TEST_TEST(bb.getElement(i)==i);
+}
+
+Test_Say("(MIC -> MIC) ==");
+aa.setLike(bb);
+aa=bb;
+TEST_TEST(aa==bb);
+TEST_TEST(!(aa!=bb));
+TEST_TEST(aa!=ee);
+bb.setElement(5,66);
+TEST_TEST(aa!=bb);
+
+Test_Say("(Host -> MIC) !=");
+aa.setLike(cc);
+aa=cc;
+TEST_TEST(aa==cc);
+aa.setElement(3,66);
+TEST_TEST(aa!=cc);
+
+Test_Say("bidn (light test)");
+dd.bind(bb,5);
+TEST_TEST(dd.getSize()==5);
+TEST_TEST(dd.getElement(1)==6);
+
+//Mylsím, že není zdaleka testováno vše...
+
+///////////////////////////////////////////////////////////////////////////////
+
+Test_Say("File Array Test: \n");
+
+//prepare arrays with data
+
+aa.setSize(10);
+ee.setSize(6);
+cc.setSize(5);
+
+//fill it UP
+/*Devices::MICHider<double> data_ptr;*/
+data_ptr.pointer= aa.getData();	
+//size=aa.getSize();
+
+#pragma offload target(mic) in(data_ptr,size)
+{
+    for(int i=0;i<size;i++)
+    {
+            data_ptr.pointer[i]=i;
+    }
+}
+
+for(int i=0;i<5;i++)
+{
+	cc[i]=10+i;
+}
+
+File soubor;
+soubor.open("/tmp/tnlArrayExperimentSave_cc.bin",IOMode::write);
+cc.save(soubor);
+soubor.close();
+
+soubor.open("/tmp/tnlArrayExperimentSave_aa.bin",IOMode::write);
+aa.save(soubor);
+soubor.close();
+
+ee.bind(aa,5,5);
+ee.boundLoad("/tmp/tnlArrayExperimentSave_cc.bin");
+
+TEST_TEST( 10 == aa.getSize())
+for(int i=0;i<5;i++)
+{
+	TEST_TEST(aa.getElement(i)==i)
+}
+for(int i=5;i<10;i++)
+{
+	TEST_TEST(aa.getElement(i)==i+5)
+}
+
+soubor.open("/tmp/tnlArrayExperimentSave_aa.bin",IOMode::read);
+cc.load(soubor);
+soubor.close();
+
+TEST_TEST( 10 == cc.getSize())
+for(int i=0;i<cc.getSize();i++)
+{
+	TEST_TEST(cc.getElement(i)==i)
+}
+
+#endif 
+
+	TEST_RESULT;
+    return 0;
+}
diff --git a/tests/mic/tnlMICVectorTest.cpp b/tests/mic/tnlMICVectorTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..058715b208c229e58b1d50a98e0c747304f679cd
--- /dev/null
+++ b/tests/mic/tnlMICVectorTest.cpp
@@ -0,0 +1,150 @@
+/***************************************************************************
+                          tnlMICVectorTest.cpp  -  
+                application testing Vector implemntation on MIC KNC
+                              by hanouvit 
+                             -------------------
+    copyright            : (C) 2004 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#include <iostream>
+#include <omp.h>
+#include <stdint.h>
+
+#include <TNL/Devices/MIC.h>
+#include <TNL/Containers/Vector.h>
+
+
+using namespace std;
+using namespace TNL;
+using namespace TNL::Containers;
+
+//TUNE MACROS FOR YOUR FUNKY OUTPUT
+#define TEST_VERBOSE
+
+unsigned int errors=0;
+unsigned int success=0;
+#define TEST_TEST(a) if((a)){cout << __LINE__ <<":\t OK" <<endl;success++;}else{cout << __LINE__<<":\t FAIL" <<endl;errors++;}
+#define TEST_RESULT cout<<"SUCCES: "<<success<<endl<<"ERRRORS: "<<errors<<endl;
+inline void Test_Say( const char * message)
+{
+#ifdef TEST_VERBOSE
+	cout << message <<endl;
+#endif
+}
+
+int main(void)
+{
+    cout << "Vector on MIC test by hanouvit:" <<endl;
+	
+    #ifdef HAVE_ICPC
+            cout << "ICPC in USE" <<endl; 
+    #endif
+
+    #ifdef HAVE_MIC
+            cout << "MIC in USE" <<endl;
+    #endif
+
+#ifdef HAVE_MIC
+        Vector<double,Devices::MIC,int> aa(10);
+        Vector<double,Devices::MIC,int> bb(10);
+        Vector<double,Devices::MIC,int> cc(10);
+
+        Vector<double,Devices::Host,int> aaa(10);
+        Vector<double,Devices::Host,int> bbb(10);
+        Vector<double,Devices::Host,int> ccc(10);
+
+        for(int i=0;i<10;i++)
+        {
+            aa.setElement(i,i-5);
+            aaa.setElement(i,i-5);
+            bb.setElement(i,5-i);
+            bbb.setElement(i,5-i);
+            cc.setElement(i,10+i);
+            ccc.setElement(i,10+i);
+        }
+
+        Test_Say("Is filled correctly?:");
+        for(int i=0;i<10;i++)
+        {
+            TEST_TEST(aa.getElement(i)==aaa.getElement(i));
+            TEST_TEST(bb.getElement(i)==bbb.getElement(i));
+            TEST_TEST(cc.getElement(i)==ccc.getElement(i));
+        }
+        
+        Test_Say("min():");
+           TEST_TEST(bb.min()==bbb.min());        
+        Test_Say("absMin():");
+           TEST_TEST(bb.absMin()==bbb.absMin());
+        Test_Say("max():");
+           TEST_TEST(bb.max()==bbb.max());
+        Test_Say("absMax():");
+           TEST_TEST(bb.absMax()==bbb.absMax());
+           
+        Test_Say("lpNorm( N ):");
+           TEST_TEST(aa.lpNorm(1)==aaa.lpNorm(1));
+           TEST_TEST(aa.lpNorm(2)==aaa.lpNorm(2));
+           TEST_TEST(aa.lpNorm(0.5)==aaa.lpNorm(0.5));
+           TEST_TEST(aa.lpNorm(3)==aaa.lpNorm(3));
+        Test_Say("sum():");
+           TEST_TEST(aa.sum()==aaa.sum());
+
+        Test_Say("differenceMax():");
+           TEST_TEST(aa.differenceMax(bb)==aaa.differenceMax(bbb));
+        Test_Say("differenceMin():");
+           TEST_TEST(aa.differenceMin(bb)==aaa.differenceMin(bbb));
+        Test_Say("differenceAbsMax():");
+           TEST_TEST(aa.differenceAbsMax(bb)==aaa.differenceAbsMax(bbb));
+        Test_Say("differenceAbsMin():");
+           TEST_TEST(aa.differenceAbsMin(bb)==aaa.differenceAbsMin(bbb));
+        Test_Say("differenceSum():");
+           TEST_TEST(aa.differenceSum(bb)==aaa.differenceSum(bbb));
+           
+        ////
+        Test_Say("differenceLpNorm( N ):");
+           TEST_TEST(aa.differenceLpNorm(bb,1)==aaa.differenceLpNorm(bbb,1));
+           TEST_TEST(aa.differenceLpNorm(bb,2)==aaa.differenceLpNorm(bbb,2));
+           TEST_TEST(aa.differenceLpNorm(bb,0.5)==aaa.differenceLpNorm(bbb,0.5));
+           TEST_TEST(aa.differenceLpNorm(bb,3)==aaa.differenceLpNorm(bbb,3));
+        
+        ////
+        Test_Say("== :");
+            TEST_TEST(aa==aaa);
+        Test_Say("vct*0.5 :");
+        aa*=0.5;
+        aaa*=0.5;
+            TEST_TEST(aa==aaa);
+        
+        Test_Say("scalarProduct :");
+            TEST_TEST(aa.scalarProduct(bb) == aaa.scalarProduct(bbb));
+
+        Test_Say("addVector :");
+        aa.addVector(bb,2.0,3.0);
+        aaa.addVector(bbb,2.0,3.0);
+            TEST_TEST(aa==aaa);            
+        aa.addVectors(bb,2.0,cc,1.0,-3.0);
+        aaa.addVectors(bbb,2.0,ccc,1.0,-3.0);
+            TEST_TEST(aa==aaa); 
+            
+        Test_Say("computeExclusivePrefixSum :");    
+        aa.computeExclusivePrefixSum();
+        aaa.computeExclusivePrefixSum();
+            TEST_TEST(aa==aaa);             
+        bb.computeExclusivePrefixSum(2,4);
+        bbb.computeExclusivePrefixSum(2,4);
+            TEST_TEST(bb==bbb); 
+            
+        Test_Say("computePrefixSum :");    
+        cc.computePrefixSum();
+        ccc.computePrefixSum();
+            TEST_TEST(cc==ccc); 
+        cc.computePrefixSum(2,4);
+        ccc.computePrefixSum(2,4);
+            TEST_TEST(cc==ccc); 	
+#endif
+	TEST_RESULT;	
+		
+    return 0;
+}
diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/core/cuda/CMakeLists.txt b/tests/unit-tests/core/cuda/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/core/cuda/tnlCudaReductionTester.h b/tests/unit-tests/core/cuda/tnlCudaReductionTester.h
index 193b95a6808b7995d49324ecc179e1ae000287de..313063b22d690c50aa375bc01a7a489500448a99 100644
--- a/tests/unit-tests/core/cuda/tnlCudaReductionTester.h
+++ b/tests/unit-tests/core/cuda/tnlCudaReductionTester.h
@@ -95,7 +95,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       for( int i = 0; i < size; i ++ )
          hostData[ i ] = value;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< RealType, RealType, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
    }
 
    template< typename RealType >
@@ -105,7 +105,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       RealType *hostData, *deviceData;
       ArrayOperations< Devices::Host >::allocateMemory( hostData, shortSequence );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, shortSequence );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       RealType result;
 
@@ -149,7 +149,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       ArrayOperations< Devices::Host >::freeMemory( hostData );
       ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
    }
 
    template< typename RealType >
@@ -159,7 +159,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       RealType *hostData, *deviceData;
       ArrayOperations< Devices::Host >::allocateMemory( hostData, longSequence );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, longSequence );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       RealType result;
 
@@ -237,7 +237,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       ArrayOperations< Devices::Host >::freeMemory( hostData );
       ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
    }
 
    template< typename RealType >
@@ -247,7 +247,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       RealType *hostData, *deviceData;
       ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       RealType sum( 0.0 );
       for( int i = 0; i < size; i ++ )
@@ -256,7 +256,7 @@ class CudaReductionTester : public CppUnit :: TestCase
          sum += hostData[ i ];
       }
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< RealType, RealType, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
       tnlParallelReductionSum< RealType, int > sumOperation;
       RealType result;
       CPPUNIT_ASSERT(
@@ -289,7 +289,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       ArrayOperations< Devices::Host >::freeMemory( hostData );
       ArrayOperations< Devices::Cuda >::freeMemory( deviceData );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
    }
 
    template< typename Type >
@@ -299,13 +299,13 @@ class CudaReductionTester : public CppUnit :: TestCase
       Type *hostData, *deviceData;
       ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
          hostData[ i ] = 1;
 
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       tnlParallelReductionLogicalAnd< Type, int > andOperation;
       tnlParallelReductionLogicalOr< Type, int > orOperation;
@@ -319,7 +319,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       hostData[ 0 ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( andOperation, size, deviceData, ( Type* ) 0, result ) ) );
       CPPUNIT_ASSERT( result == 0 );
@@ -331,7 +331,7 @@ class CudaReductionTester : public CppUnit :: TestCase
          hostData[ i ] = 0;
 
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( andOperation, size, deviceData, ( Type* ) 0, result ) ) );
       CPPUNIT_ASSERT( result == 0 );
@@ -347,13 +347,13 @@ class CudaReductionTester : public CppUnit :: TestCase
       Type *hostData, *deviceData;
       ArrayOperations< Devices::Host >::allocateMemory( hostData, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
          hostData[ i ] = 1;
 
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       tnlParallelReductionLogicalAnd< Type, int > andOperation;
       tnlParallelReductionLogicalOr< Type, int > orOperation;
@@ -367,7 +367,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       hostData[ 0 ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( andOperation, size, deviceData, ( Type* ) 0, result ) ) );
       CPPUNIT_ASSERT( result == 0 );
@@ -379,7 +379,7 @@ class CudaReductionTester : public CppUnit :: TestCase
          hostData[ i ] = 0;
 
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData, hostData, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( andOperation, size, deviceData, ( Type* ) 0, result ) ) );
       CPPUNIT_ASSERT( result == 0 );
@@ -398,13 +398,13 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData1, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
          hostData1[ i ] = hostData2[ i ] = 1;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData2, hostData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       bool result( false );
       tnlParallelReductionEqualities< Type, int > equalityOperation;
@@ -420,7 +420,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       hostData1[ 0 ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( equalityOperation, size, deviceData1, deviceData2, result ) ) );
@@ -433,7 +433,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       for( int i = 0; i < size; i ++ )
          hostData1[ i ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( equalityOperation, size, deviceData1, deviceData2, result ) ) );
@@ -454,13 +454,13 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData1, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
          hostData1[ i ] = hostData2[ i ] = 1;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData2, hostData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       bool result( false );
       tnlParallelReductionEqualities< Type, int > equalityOperation;
@@ -476,7 +476,7 @@ class CudaReductionTester : public CppUnit :: TestCase
 
       hostData1[ 0 ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( equalityOperation, size, deviceData1, deviceData2, result ) ) );
@@ -489,7 +489,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       for( int i = 0; i < size; i ++ )
          hostData1[ i ] = 0;
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       CPPUNIT_ASSERT(
           ( reductionOnCudaDevice( equalityOperation, size, deviceData1, deviceData2, result ) ) );
@@ -510,7 +510,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData1, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       hostData1[ 0 ] = 0;
       hostData2[ 0 ] = 1;
@@ -523,7 +523,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       }
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData2, hostData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       Type result( 0.0 );
       tnlParallelReductionScalarProduct< Type, int > scalarProductOperation;
@@ -544,7 +544,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Host >::allocateMemory( hostData2, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData1, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       hostData1[ 0 ] = 0;
       hostData2[ 0 ] = 1;
@@ -557,7 +557,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       }
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData1, hostData1, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceData2, hostData2, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       Type result( 0.0 );
       tnlParallelReductionScalarProduct< Type, int > scalarProductOperation;
@@ -579,7 +579,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceZeros, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceOnes, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceLinear, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
       {
@@ -591,7 +591,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceZeros, hostZeros, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceOnes, hostOnes, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceLinear, hostLinear, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       tnlParallelReductionDiffSum< Type, int > diffSumOp;
       tnlParallelReductionDiffMin< Type, int > diffMinOp;
@@ -696,7 +696,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceZeros, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceOnes, size );
       ArrayOperations< Devices::Cuda >::allocateMemory( deviceLinear, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       for( int i = 0; i < size; i ++ )
       {
@@ -708,7 +708,7 @@ class CudaReductionTester : public CppUnit :: TestCase
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceZeros, hostZeros, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceOnes, hostOnes, size );
       ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory< Type, Type, int >( deviceLinear, hostLinear, size );
-      CPPUNIT_ASSERT( checkCudaDevice );
+      CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 
       tnlParallelReductionDiffSum< Type, int > diffSumOp;
       tnlParallelReductionDiffMin< Type, int > diffMinOp;
diff --git a/tests/unit-tests/core/cuda/tnlCudaTester.h b/tests/unit-tests/core/cuda/tnlCudaTester.h
index 5c2024cbcc5dcdb70c4ad90b15d70d400bf36649..3cb033c53b7812510f22d3d1b976b9eeee6bd267 100644
--- a/tests/unit-tests/core/cuda/tnlCudaTester.h
+++ b/tests/unit-tests/core/cuda/tnlCudaTester.h
@@ -59,7 +59,7 @@ class Devices::CudaTester : public CppUnit :: TestCase
       blockSize. x = 1;
       gridSize. x = 1;
       simpleKernel<<< gridSize, blockSize >>>();
-      if( ! checkCudaDevice )
+      if( ! TNL_CHECK_CUDA_DEVICE )
       {
          std::cerr << "Test with simple kernel failed. It seems that the CUDA device does not work properly." << std::endl;
          CPPUNIT_ASSERT( false );
diff --git a/tests/unit-tests/core/multimaps/tnlIndexMultimapTester.h b/tests/unit-tests/core/multimaps/tnlIndexMultimapTester.h
index b7951a294bf75c0bf79c899d47dba6a0e1c8a125..236a608e5601791fec44f134a00436629e4352d5 100644
--- a/tests/unit-tests/core/multimaps/tnlIndexMultimapTester.h
+++ b/tests/unit-tests/core/multimaps/tnlIndexMultimapTester.h
@@ -152,7 +152,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexVector rowLengths;
          rowLengths.setSize( m1.getRows() );
          rowLengths.setValue( 5 );
-         m1.setCompressedRowsLengths( rowLengths );
+         m1.setCompressedRowLengths( rowLengths );
          m2.setLike( m1 );
          CPPUNIT_ASSERT( m1.getRows() == m2.getRows() );
       }*/
@@ -193,7 +193,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::getDevice() == Devices::HostDevice )
       {
@@ -208,7 +208,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFastTestCudaKernel< IndexMultimapType >
                                                             <<< cudaGridSize, cudaBlockSize >>>
@@ -217,7 +217,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -233,7 +233,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -258,7 +258,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
@@ -271,7 +271,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFast_DiagonalIndexMultimapTestCudaKernel< IndexMultimapType >
                                                                            <<< cudaGridSize, cudaBlockSize >>>
@@ -280,7 +280,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -304,7 +304,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -321,7 +321,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = 9; j >= 0; j-- )
             m.setElement( i, j, i+j );
@@ -339,7 +339,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
@@ -355,7 +355,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFast_DenseIndexMultimapTestCudaKernel1< IndexMultimapType >
                                                                          <<< cudaGridSize, cudaBlockSize >>>
@@ -364,7 +364,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -377,7 +377,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
          for( int i = 9; i >= 0; i-- )
@@ -390,7 +390,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFast_DenseIndexMultimapTestCudaKernel2< IndexMultimapType >
                                                                          <<< cudaGridSize, cudaBlockSize >>>
@@ -399,7 +399,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -418,7 +418,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          for( int j = 0; j <= i; j++ )
@@ -433,7 +433,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = i; j >= 0; j-- )
             m.setElement( i, j, i + j );
@@ -455,7 +455,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
@@ -469,7 +469,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFast_LowerTriangularIndexMultimapTestCudaKernel1< IndexMultimapType >
                                                                                    <<< cudaGridSize, cudaBlockSize >>>
@@ -478,7 +478,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -491,7 +491,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
          for( int i = 9; i >= 0; i-- )
@@ -504,7 +504,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          tnlIndexMultimapTester__setElementFast_LowerTriangularIndexMultimapTestCudaKernel2< IndexMultimapType >
                                                                                    <<< cudaGridSize, cudaBlockSize >>>
@@ -513,7 +513,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -534,7 +534,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
       for( int i = 0; i < 10; i++ )
@@ -564,7 +564,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       RealType values[ 1 ];
       IndexType columnIndexes[ 1 ];
 
@@ -595,7 +595,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
@@ -615,7 +615,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          tnlIndexMultimapTester__setRowFast_DiagonalIndexMultimapTestCudaKernel< IndexMultimapType >
@@ -625,7 +625,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -649,7 +649,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       RealType values[ 10 ];
       IndexType columnIndexes[ 10 ];
 
@@ -675,7 +675,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
       {
          for( int j = 9; j >= 0; j-- )
@@ -696,7 +696,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       RealType values[ 10 ];
       IndexType columnIndexes[ 10 ];
@@ -722,7 +722,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          tnlIndexMultimapTester__setRowFast_DenseIndexMultimapTestCudaKernel1< IndexMultimapType >
@@ -732,7 +732,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -745,7 +745,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
@@ -762,7 +762,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          tnlIndexMultimapTester__setRowFast_DenseIndexMultimapTestCudaKernel2< IndexMultimapType >
@@ -772,7 +772,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -790,7 +790,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       RealType values[ 10 ];
@@ -815,7 +815,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
       {
          for( int j = i; j >= 0; j-- )
@@ -840,7 +840,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       RealType values[ 10 ];
@@ -863,7 +863,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          tnlIndexMultimapTester__setRowFast_LowerTriangularIndexMultimapTestCudaKernel< IndexMultimapType >
@@ -873,7 +873,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -886,7 +886,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( DeviceType::DeviceType == ( int ) Devices::HostDevice )
       {
@@ -903,7 +903,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          IndexMultimapType* kernel_graph = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          tnlIndexMultimapTester__setRowFast_LowerTriangularIndexMultimapTestCudaKernel< IndexMultimapType >
@@ -913,7 +913,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_graph );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -938,7 +938,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          v.setElement( i, i );
@@ -962,7 +962,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( size );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          for( int j = 0; j < size; j++ )
@@ -987,7 +987,7 @@ class tnlIndexMultimapTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( size );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          for( int j = 0; j <= i; j++ )
diff --git a/tests/unit-tests/functions/tnlOperatorFunctionTest.h b/tests/unit-tests/functions/tnlOperatorFunctionTest.h
index 302f0295a6a440ac38bb6559063993667be46cab..d50852c60d3929e4c388d6774c8c1702fc185583 100644
--- a/tests/unit-tests/functions/tnlOperatorFunctionTest.h
+++ b/tests/unit-tests/functions/tnlOperatorFunctionTest.h
@@ -40,9 +40,9 @@ class OperatorFunctionTest
    typedef typename OperatorType::RealType RealType;
    typedef typename OperatorType::IndexType IndexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
-   typedef typename MeshType::VertexType VertexType;
-   typedef Functions::Analytic::ExpBump< MeshType::getMeshDimensions(), RealType > TestFunctionType;
-   typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimensions() > MeshFunctionType;
+   typedef typename MeshType::PointType PointType;
+   typedef Functions::Analytic::ExpBump< MeshType::getMeshDimension(), RealType > TestFunctionType;
+   typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimension() > MeshFunctionType;
    typedef SharedPointer< MeshType > MeshPointer;
 
    OperatorFunctionTest(){};
@@ -65,7 +65,7 @@ class OperatorFunctionTest
       MeshPointer meshPointer;
       typedef Functions::OperatorFunction< Operator, MeshFunctionType, void, EvaluateOnFly > OperatorFunctionType;
       meshPointer->setDimensions( CoordinatesType( 25 ) );
-      meshPointer->setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      meshPointer->setDomain( PointType( -1.0 ), PointType( 2.0 ) );
       TestFunctionType testFunction;
       testFunction.setAmplitude( 1.0 );
       testFunction.setSigma( 1.0 );
@@ -94,7 +94,7 @@ class OperatorFunctionTest
       typedef Operators::DirichletBoundaryConditions< MeshType > BoundaryConditionsType;
       typedef Functions::OperatorFunction< Operator, MeshFunctionType, BoundaryConditionsType, EvaluateOnFly > OperatorFunctionType;
       mesh->setDimensions( CoordinatesType( 25 ) );
-      mesh->setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      mesh->setDomain( PointType( -1.0 ), PointType( 2.0 ) );
       TestFunctionType testFunction;
       testFunction.setAmplitude( 1.0 );
       testFunction.setSigma( 1.0 );
diff --git a/tests/unit-tests/matrices/CMakeLists.txt b/tests/unit-tests/matrices/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/matrices/tnlChunkedEllpackMatrixTester.h b/tests/unit-tests/matrices/tnlChunkedEllpackMatrixTester.h
index f5acdf0f5dabe2b7c47e6bec9e63ce5da38e3b9f..a98a85ab103f1354481a1d67f926f7f4b2c650db 100644
--- a/tests/unit-tests/matrices/tnlChunkedEllpackMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlChunkedEllpackMatrixTester.h
@@ -80,7 +80,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m1.getRows() );
       rowLengths.setValue( 5 );
-      m1.setCompressedRowsLengths( rowLengths );
+      m1.setCompressedRowLengths( rowLengths );
       m2.setLike( m1 );
       CPPUNIT_ASSERT( m1.getRows() == m2.getRows() );
    }
@@ -95,7 +95,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 7; i++ )
          CPPUNIT_ASSERT( m.setElement( 0, i, i ) );
@@ -112,7 +112,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -139,7 +139,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -159,7 +159,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       m.setDimensions( 10, 10 );
       m.setNumberOfChunksInSlice( SliceSize );
       m.setDesiredChunkSize( ChunkSize );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = 9; j >= 0; j-- )
             m.setElement( i, j, i+j );
@@ -180,7 +180,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          for( int j = 0; j <= i; j++ )
@@ -195,7 +195,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = i; j >= 0; j-- )
             m.setElement( i, j, i + j );
@@ -218,7 +218,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
       for( int i = 0; i < 10; i++ )
@@ -251,7 +251,7 @@ class ChunkedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          v.setElement( i, i );
diff --git a/tests/unit-tests/matrices/tnlDenseMatrixTester.h b/tests/unit-tests/matrices/tnlDenseMatrixTester.h
index 7e7d0db2ec32600180c573b8ce569f85eb213363..b2c89e27fea7c0fa04371daab0d0f251f3d3cd2a 100644
--- a/tests/unit-tests/matrices/tnlDenseMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlDenseMatrixTester.h
@@ -100,11 +100,11 @@ class DenseTester : public CppUnit :: TestCase
       {
 #ifdef HAVE_CUDA
          MatrixType* kernel_m = Devices::Cuda::passToDevice( m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          setElementFastTestKernel<<< 1, 16 >>>( kernel_m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          Devices::Cuda::freeFromDevice( kernel_m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 #endif
       }
       for( int i = 0; i < 10; i++ )
@@ -145,11 +145,11 @@ class DenseTester : public CppUnit :: TestCase
       {
 #ifdef HAVE_CUDA
          MatrixType* kernel_m = Devices::Cuda::passToDevice( m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          addElementFastTestKernel<<< 1, 128 >>>( kernel_m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          Devices::Cuda::freeFromDevice( kernel_m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 #endif
       }
       for( int i = 0; i < 10; i++ )
@@ -216,11 +216,11 @@ class DenseTester : public CppUnit :: TestCase
       {
 #ifdef HAVE_CUDA
          MatrixType* kernel_m = Devices::Cuda::passToDevice( m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          setRowFastTestKernel<<< 1, 128 >>>( kernel_m, columns.getData(), values.getData(), ( IndexType ) 10 );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
          Devices::Cuda::freeFromDevice( kernel_m );
-         CPPUNIT_ASSERT( checkCudaDevice );
+         CPPUNIT_ASSERT( TNL_CHECK_CUDA_DEVICE );
 #endif
       }
 
diff --git a/tests/unit-tests/matrices/tnlEllpackMatrixTester.h b/tests/unit-tests/matrices/tnlEllpackMatrixTester.h
index d4042a6465b52118d6ec1c18cf97bed0b794d349..f6982932826c87eab6c48278e1f46a0e2ca21981 100644
--- a/tests/unit-tests/matrices/tnlEllpackMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlEllpackMatrixTester.h
@@ -67,7 +67,7 @@ class EllpackTester : public CppUnit :: TestCase
    {
       MatrixType m1, m2;
       m1.setDimensions( 10, 10 );
-      m1.setConstantCompressedRowsLengths( 5 );
+      m1.setConstantCompressedRowLengths( 5 );
       m2.setLike( m1 );
       CPPUNIT_ASSERT( m1.getRows() == m2.getRows() );
    }
@@ -76,7 +76,7 @@ class EllpackTester : public CppUnit :: TestCase
    {
       MatrixType m;
       m.setDimensions( 10, 10 );
-      m.setConstantCompressedRowsLengths( 7 );
+      m.setConstantCompressedRowLengths( 7 );
 
       for( int i = 0; i < 7; i++ )
          CPPUNIT_ASSERT( m.setElement( 0, i, i ) );
@@ -87,7 +87,7 @@ class EllpackTester : public CppUnit :: TestCase
    {
       MatrixType m;
       m.setDimensions( 10, 10 );
-      m.setConstantCompressedRowsLengths( 7 );
+      m.setConstantCompressedRowLengths( 7 );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -103,7 +103,7 @@ class EllpackTester : public CppUnit :: TestCase
    {
       MatrixType m;
       m.setDimensions( 10, 10 );
-      m.setConstantCompressedRowsLengths( 10 );
+      m.setConstantCompressedRowLengths( 10 );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -120,7 +120,7 @@ class EllpackTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setConstantCompressedRowsLengths( 10 );
+      m.setConstantCompressedRowLengths( 10 );
       for( int i = 9; i >= 0; i-- )
          for( int j = 9; j >= 0; j-- )
             m.setElement( i, j, i+j );
@@ -134,7 +134,7 @@ class EllpackTester : public CppUnit :: TestCase
    {
       MatrixType m;
       m.setDimensions( 10, 10 );
-      m.setConstantCompressedRowsLengths( 7 );
+      m.setConstantCompressedRowLengths( 7 );
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
       for( int i = 0; i < 10; i++ )
@@ -161,7 +161,7 @@ class EllpackTester : public CppUnit :: TestCase
       w.setSize( size );
       MatrixType m;
       m.setDimensions( size, size );
-      m.setConstantCompressedRowsLengths( 7 );
+      m.setConstantCompressedRowLengths( 7 );
       for( int i = 0; i < size; i++ )
       {
          v.setElement( i, i );
diff --git a/tests/unit-tests/matrices/tnlSlicedEllpackMatrixTester.h b/tests/unit-tests/matrices/tnlSlicedEllpackMatrixTester.h
index 4a4cb7bac11f669cb68628f56b7b166c5cfc6e6c..32e4443f5291e06f5817e21f48b3a5e6866d9ab3 100644
--- a/tests/unit-tests/matrices/tnlSlicedEllpackMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlSlicedEllpackMatrixTester.h
@@ -72,7 +72,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m1.getRows() );
       rowLengths.setValue( 5 );
-      m1.setCompressedRowsLengths( rowLengths );
+      m1.setCompressedRowLengths( rowLengths );
       m2.setLike( m1 );
       CPPUNIT_ASSERT( m1.getRows() == m2.getRows() );
    }
@@ -84,7 +84,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 7; i++ )
          CPPUNIT_ASSERT( m.setElement( 0, i, i ) );
@@ -98,7 +98,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -122,7 +122,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -139,7 +139,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = 9; j >= 0; j-- )
             m.setElement( i, j, i+j );
@@ -157,7 +157,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          for( int j = 0; j <= i; j++ )
@@ -172,7 +172,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = i; j >= 0; j-- )
             m.setElement( i, j, i + j );
@@ -192,7 +192,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
       for( int i = 0; i < 10; i++ )
@@ -222,7 +222,7 @@ class SlicedEllpackTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          v.setElement( i, i );
diff --git a/tests/unit-tests/matrices/tnlSparseMatrixTester.h b/tests/unit-tests/matrices/tnlSparseMatrixTester.h
index ea1fd9c9ff0a7e883a56ae2792c161267a3c2863..b2b29c0e4c254a23756488fd57b1a65d151b6f50 100644
--- a/tests/unit-tests/matrices/tnlSparseMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlSparseMatrixTester.h
@@ -155,7 +155,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m1.getRows() );
       rowLengths.setValue( 5 );
-      m1.setCompressedRowsLengths( rowLengths );
+      m1.setCompressedRowLengths( rowLengths );
       m2.setLike( m1 );
       CPPUNIT_ASSERT( m1.getRows() == m2.getRows() );
    }
@@ -171,7 +171,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 7; i++ )
          CPPUNIT_ASSERT( m.setElement( 0, i, i ) );
@@ -191,7 +191,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -206,7 +206,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFastTestCudaKernel< MatrixType >
                                                             <<< cudaGridSize, cudaBlockSize >>>
@@ -215,7 +215,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -231,7 +231,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -256,7 +256,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -269,7 +269,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFast_DiagonalMatrixTestCudaKernel< MatrixType >
                                                                            <<< cudaGridSize, cudaBlockSize >>>
@@ -278,7 +278,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -302,7 +302,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
@@ -319,7 +319,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = 9; j >= 0; j-- )
             m.setElement( i, j, i+j );
@@ -337,7 +337,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -353,7 +353,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFast_DenseTestCudaKernel1< MatrixType >
                                                                          <<< cudaGridSize, cudaBlockSize >>>
@@ -362,7 +362,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -375,7 +375,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
          for( int i = 9; i >= 0; i-- )
@@ -388,7 +388,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFast_DenseTestCudaKernel2< MatrixType >
                                                                          <<< cudaGridSize, cudaBlockSize >>>
@@ -397,7 +397,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -416,7 +416,7 @@ class SparseTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       for( int i = 0; i < 10; i++ )
          for( int j = 0; j <= i; j++ )
@@ -431,7 +431,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
          for( int j = i; j >= 0; j-- )
             m.setElement( i, j, i + j );
@@ -453,7 +453,7 @@ class SparseTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -467,7 +467,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFast_LowerTriangularMatrixTestCudaKernel1< MatrixType >
                                                                                    <<< cudaGridSize, cudaBlockSize >>>
@@ -476,7 +476,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -489,7 +489,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
          for( int i = 9; i >= 0; i-- )
@@ -502,7 +502,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          SparseTester__setElementFast_LowerTriangularMatrixTestCudaKernel2< MatrixType >
                                                                                    <<< cudaGridSize, cudaBlockSize >>>
@@ -511,7 +511,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -532,7 +532,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < 10; i++ )
          m.setElement( i, i, i );
       for( int i = 0; i < 10; i++ )
@@ -562,7 +562,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       RealType values[ 1 ];
       IndexType columnIndexes[ 1 ];
 
@@ -593,7 +593,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       if( std::is_same< DeviceType, Devices::Host >::value )
@@ -613,7 +613,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          SparseTester__setRowFast_DiagonalMatrixTestCudaKernel< MatrixType >
@@ -623,7 +623,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -647,7 +647,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       RealType values[ 10 ];
       IndexType columnIndexes[ 10 ];
 
@@ -673,7 +673,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
       {
          for( int j = 9; j >= 0; j-- )
@@ -694,7 +694,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       RealType values[ 10 ];
       IndexType columnIndexes[ 10 ];
@@ -720,7 +720,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          SparseTester__setRowFast_DenseTestCudaKernel1< MatrixType >
@@ -730,7 +730,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -743,7 +743,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -760,7 +760,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          SparseTester__setRowFast_DenseTestCudaKernel2< MatrixType >
@@ -770,7 +770,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -788,7 +788,7 @@ class SparseTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       RealType values[ 10 ];
@@ -813,7 +813,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 9; i >= 0; i-- )
       {
          for( int j = i; j >= 0; j-- )
@@ -838,7 +838,7 @@ class SparseTester : public CppUnit :: TestCase
       rowLengths.setSize( m.getRows() );
       for( int i = 0; i < 10; i++ )
          rowLengths.setElement( i, i+1 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
 
       RealType values[ 10 ];
@@ -861,7 +861,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          SparseTester__setRowFast_LowerTriangularMatrixTestCudaKernel< MatrixType >
@@ -871,7 +871,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -884,7 +884,7 @@ class SparseTester : public CppUnit :: TestCase
 
       m.reset();
       m.setDimensions( 10, 10 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
 
       if( std::is_same< DeviceType, Devices::Host >::value )
       {
@@ -901,7 +901,7 @@ class SparseTester : public CppUnit :: TestCase
          MatrixType* kernel_matrix = Devices::Cuda::passToDevice( m );
          bool testResult( true );
          bool* kernel_testResult = Devices::Cuda::passToDevice( testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
          dim3 cudaBlockSize( 256 ), cudaGridSize( 1 );
          int sharedMemory = 100 * ( sizeof( IndexType ) + sizeof( RealType ) );
          SparseTester__setRowFast_LowerTriangularMatrixTestCudaKernel< MatrixType >
@@ -911,7 +911,7 @@ class SparseTester : public CppUnit :: TestCase
          CPPUNIT_ASSERT( Devices::Cuda::passFromDevice( kernel_testResult ) );
          Devices::Cuda::freeFromDevice( kernel_matrix );
          Devices::Cuda::freeFromDevice( kernel_testResult );
-         checkCudaDevice;
+         TNL_CHECK_CUDA_DEVICE;
 #endif
       }
 
@@ -936,7 +936,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( 7 );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          v.setElement( i, i );
@@ -960,7 +960,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( size );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          for( int j = 0; j < size; j++ )
@@ -985,7 +985,7 @@ class SparseTester : public CppUnit :: TestCase
       IndexVector rowLengths;
       rowLengths.setSize( m.getRows() );
       rowLengths.setValue( size );
-      m.setCompressedRowsLengths( rowLengths );
+      m.setCompressedRowLengths( rowLengths );
       for( int i = 0; i < size; i++ )
       {
          for( int j = 0; j <= i; j++ )
diff --git a/tests/unit-tests/mesh/CMakeLists.txt b/tests/unit-tests/mesh/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/mesh/tnlGrid1DTester.h b/tests/unit-tests/mesh/tnlGrid1DTester.h
index 6e56d5810deb6578f3369068199e47406c5d5e4a..c5d8c8a7377b292c07157e0d32d00cbe8b97eb3b 100644
--- a/tests/unit-tests/mesh/tnlGrid1DTester.h
+++ b/tests/unit-tests/mesh/tnlGrid1DTester.h
@@ -21,7 +21,7 @@ class GridTester< 1, RealType, Device, IndexType >: public CppUnit :: TestCase
    typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
    typedef Meshes::Grid< 1, RealType, Device, IndexType > GridType;
    typedef typename GridType::CoordinatesType CoordinatesType;
-   typedef typename GridType::VertexType VertexType;
+   typedef typename GridType::PointType PointType;
 
    GridTester(){};
 
@@ -42,7 +42,7 @@ class GridTester< 1, RealType, Device, IndexType >: public CppUnit :: TestCase
    void setDomainTest()
    {
       GridType grid;
-      grid.setDomain( VertexType( 0.0 ), VertexType( 1.0 ) );
+      grid.setDomain( PointType( 0.0 ), PointType( 1.0 ) );
       grid.setDimensions( 10 );
 
       CPPUNIT_ASSERT( grid.getSpaceSteps().x() == 0.1 );
@@ -71,14 +71,14 @@ class GridTester< 1, RealType, Device, IndexType >: public CppUnit :: TestCase
       GridType grid;
       grid.setDimensions( xSize );
 
-      typename GridType::Vertex vertex( grid );
+      typename GridType::Point vertex( grid );
       for( vertex.getCoordinates().x() = 0;
            vertex.getCoordinates().x() < xSize;
            vertex.getCoordinates().x()++ )
       {
          CPPUNIT_ASSERT( grid.getEntityIndex( vertex ) >= 0 );
-         CPPUNIT_ASSERT( grid.getEntityIndex( vertex ) < grid.template getEntitiesCount< typename GridType::Vertex >() );
-         CPPUNIT_ASSERT( grid.template getEntity< typename GridType::Vertex >( grid.getEntityIndex( vertex ) ).getCoordinates() == vertex.getCoordinates() );
+         CPPUNIT_ASSERT( grid.getEntityIndex( vertex ) < grid.template getEntitiesCount< typename GridType::Point >() );
+         CPPUNIT_ASSERT( grid.template getEntity< typename GridType::Point >( grid.getEntityIndex( vertex ) ).getCoordinates() == vertex.getCoordinates() );
       }
    }
 
diff --git a/tests/unit-tests/mesh/tnlGrid2DTester.h b/tests/unit-tests/mesh/tnlGrid2DTester.h
index c80d92115d5581bc382df65f4d005ac238dcbc82..fcb9b47131f90684d0538d0d67a3842073ca1dd3 100644
--- a/tests/unit-tests/mesh/tnlGrid2DTester.h
+++ b/tests/unit-tests/mesh/tnlGrid2DTester.h
@@ -21,7 +21,7 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
    typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
    typedef Meshes::Grid< 2, RealType, Device, IndexType > GridType;
    typedef typename GridType::CoordinatesType CoordinatesType;
-   typedef typename GridType::VertexType VertexType;
+   typedef typename GridType::PointType PointType;
 
 
    GridTester(){};
@@ -48,7 +48,7 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
    void setDomainTest()
    {
       GridType grid;
-      grid.setDomain( VertexType( 0.0, 0.0 ), VertexType( 1.0, 1.0 ) );
+      grid.setDomain( PointType( 0.0, 0.0 ), PointType( 1.0, 1.0 ) );
       grid.setDimensions( 10, 20 );
 
       CPPUNIT_ASSERT( grid.getSpaceSteps().x() == 0.1 );
@@ -130,9 +130,9 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
       const IndexType ySize( 17 );
       GridType grid;
  
-      typedef typename GridType::template MeshEntity< 0 > VertexType;
-      typedef typename VertexType::EntityBasisType BasisType;
-      VertexType vertex( grid );
+      typedef typename GridType::template MeshEntity< 0 > PointType;
+      typedef typename PointType::EntityBasisType BasisType;
+      PointType vertex( grid );
  
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
       grid.setDimensions( xSize, ySize );
@@ -143,10 +143,10 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
               vertex.getCoordinates().x() < xSize + 1;
               vertex.getCoordinates().x()++ )
          {
-            const IndexType vertexIndex = grid.template getEntityIndex< typename GridType::Vertex >( vertex );
+            const IndexType vertexIndex = grid.template getEntityIndex< typename GridType::Point >( vertex );
             CPPUNIT_ASSERT( vertexIndex >= 0 );
-            CPPUNIT_ASSERT( vertexIndex < grid.template getEntitiesCount< typename GridType::Vertex >() );
-            CPPUNIT_ASSERT( grid.template getEntity< typename GridType::Vertex >( vertexIndex ).getCoordinates() == vertex.getCoordinates() );
+            CPPUNIT_ASSERT( vertexIndex < grid.template getEntitiesCount< typename GridType::Point >() );
+            CPPUNIT_ASSERT( grid.template getEntity< typename GridType::Point >( vertexIndex ).getCoordinates() == vertex.getCoordinates() );
          }
    }
 
@@ -174,29 +174,29 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
             {
                const CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( -1, 0 ) );
                const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-               auto neighbourEntities = cell.getNeighbourEntities();
-               CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< -1, 0 >() ) );
+               auto neighborEntities = cell.getNeighborEntities();
+               CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< -1, 0 >() ) );
             }
             if( cell.getCoordinates().x() < xSize - 1 )
             {
                const CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 1, 0 ) );
                const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-               auto neighbourEntities = cell.getNeighbourEntities();
-               CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 1, 0 >() ) );
+               auto neighborEntities = cell.getNeighborEntities();
+               CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 1, 0 >() ) );
             }
             if( cell.getCoordinates().y() > 0 )
             {
                const CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, -1 ) );
                const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-               auto neighbourEntities = cell.getNeighbourEntities();
-               CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, -1 >() ) );
+               auto neighborEntities = cell.getNeighborEntities();
+               CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, -1 >() ) );
             }
             if( cell.getCoordinates().y() < ySize - 1 )
             {
                const CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, 1 ) );
                const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-               auto neighbourEntities = cell.getNeighbourEntities();
-               CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, 1 >() ) );
+               auto neighborEntities = cell.getNeighborEntities();
+               CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, 1 >() ) );
             }
          }
    }
@@ -224,35 +224,35 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
          {
             //const IndexType cellIndex = grid.getEntityIndex( cell );
             cell.refresh(); //setIndex( cellIndex );
-            auto neighbourEntities = cell.template getNeighbourEntities< GridType::Face::entityDimensions >();
+            auto neighborEntities = cell.template getNeighborEntities< GridType::Face::entityDimension >();
 
             FaceType face1( grid,
                             cell.getCoordinates(),
                             EntityOrientationType( -1, 0 ),
                             EntityBasisType( 0, 1 ) );
             IndexType face1Index = grid.template getEntityIndex( face1 );
-            CPPUNIT_ASSERT( ( face1Index == neighbourEntities.template getEntityIndex< -1, 0 >() ) );
+            CPPUNIT_ASSERT( ( face1Index == neighborEntities.template getEntityIndex< -1, 0 >() ) );
 
             FaceType face2( grid,
                             cell.getCoordinates() + CoordinatesType( 1, 0 ),
                             EntityOrientationType( 1, 0 ),
                             EntityBasisType( 0, 1 ) );
             IndexType face2Index = grid.template getEntityIndex( face2 );
-            CPPUNIT_ASSERT( ( face2Index == neighbourEntities.template getEntityIndex< 1, 0 >() ) );
+            CPPUNIT_ASSERT( ( face2Index == neighborEntities.template getEntityIndex< 1, 0 >() ) );
 
             FaceType face3( grid,
                             cell.getCoordinates(),
                             EntityOrientationType( 0, -1 ),
                             EntityBasisType( 1, 0 ) );
             IndexType face3Index = grid.template getEntityIndex( face3 );
-            CPPUNIT_ASSERT( ( face3Index == neighbourEntities.template getEntityIndex< 0, -1 >() ) );
+            CPPUNIT_ASSERT( ( face3Index == neighborEntities.template getEntityIndex< 0, -1 >() ) );
  
             FaceType face4( grid,
                             cell.getCoordinates() + CoordinatesType( 0, 1 ),
                             EntityOrientationType( 0, 1 ),
                             EntityBasisType( 1, 0 ) );
             IndexType face4Index = grid.template getEntityIndex( face4 );
-            CPPUNIT_ASSERT( ( face4Index == neighbourEntities.template getEntityIndex< 0, 1 >() ) );
+            CPPUNIT_ASSERT( ( face4Index == neighborEntities.template getEntityIndex< 0, 1 >() ) );
          }
    }
 
@@ -281,20 +281,20 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
                face.setOrientation( EntityOrientationType( 1, 0 ) );
                //const IndexType faceIndex = grid.getEntityIndex( face );
                face.refresh(); //setIndex( faceIndex );
-               auto neighbourCells = face.template getNeighbourEntities< GridType::Cell::entityDimensions >();
+               auto neighborCells = face.template getNeighborEntities< GridType::Cell::entityDimension >();
 
 
                if( face.getCoordinates().x() > 0 )
                {
                   CellType cell( grid, face.getCoordinates() + CoordinatesType( -1, 0 ) );
                   IndexType cellIndex = grid.getEntityIndex( cell );
-                  CPPUNIT_ASSERT( ( cellIndex == neighbourCells.template getEntityIndex< -1, 0 >() ) );
+                  CPPUNIT_ASSERT( ( cellIndex == neighborCells.template getEntityIndex< -1, 0 >() ) );
                }
                if( face.getCoordinates().x() < xSize )
                {
                   CellType cell( grid, face.getCoordinates() + CoordinatesType( 0, 0 ) );
                   IndexType cellIndex = grid.getEntityIndex( cell );
-                  CPPUNIT_ASSERT( ( cellIndex == neighbourCells.template getEntityIndex< 1, 0 >() ) );
+                  CPPUNIT_ASSERT( ( cellIndex == neighborCells.template getEntityIndex< 1, 0 >() ) );
                }
             }
             if( face.getCoordinates().x() < xSize )
@@ -302,19 +302,19 @@ class GridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCase
                face.setOrientation( EntityOrientationType( 0, 1 ) );
                //const IndexType faceIndex = grid.getEntityIndex( face );
                face.refresh();//setIndex( faceIndex );
-               auto neighbourCells = face.template getNeighbourEntities< GridType::Cell::entityDimensions >();
+               auto neighborCells = face.template getNeighborEntities< GridType::Cell::entityDimension >();
  
                if( face.getCoordinates().y() > 0 )
                {
                   CellType cell( grid, face.getCoordinates() + CoordinatesType( 0, -1 ) );
                   IndexType cellIndex = grid.getEntityIndex( cell );
-                  CPPUNIT_ASSERT( ( cellIndex == neighbourCells.template getEntityIndex< 0, -1 >() ) );
+                  CPPUNIT_ASSERT( ( cellIndex == neighborCells.template getEntityIndex< 0, -1 >() ) );
                }
                if( face.getCoordinates().y() < ySize )
                {
                   CellType cell( grid, face.getCoordinates() + CoordinatesType( 0, 0 ) );
                   IndexType cellIndex = grid.getEntityIndex( cell );
-                  CPPUNIT_ASSERT( ( cellIndex == neighbourCells.template getEntityIndex< 0, 1 >() ) );
+                  CPPUNIT_ASSERT( ( cellIndex == neighborCells.template getEntityIndex< 0, 1 >() ) );
                }
             }
          }
diff --git a/tests/unit-tests/mesh/tnlGrid3DTester.h b/tests/unit-tests/mesh/tnlGrid3DTester.h
index e6dd2249a7c118fca6251f17370153fd08ac5353..fed97012f5fcb2305e6ec0d3d582e7c6e8f98231 100644
--- a/tests/unit-tests/mesh/tnlGrid3DTester.h
+++ b/tests/unit-tests/mesh/tnlGrid3DTester.h
@@ -21,7 +21,7 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
    typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
    typedef Meshes::Grid< 3, RealType, Device, IndexType > GridType;
    typedef typename GridType::CoordinatesType CoordinatesType;
-   typedef typename GridType::VertexType VertexType;
+   typedef typename GridType::PointType PointType;
 
 
    GridTester(){};
@@ -50,7 +50,7 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
    void setDomainTest()
    {
       GridType grid;
-      grid.setDomain( VertexType( 0.0, 0.0, 0.0 ), VertexType( 1.0, 1.0, 1.0 ) );
+      grid.setDomain( PointType( 0.0, 0.0, 0.0 ), PointType( 1.0, 1.0, 1.0 ) );
       grid.setDimensions( 10, 20, 40 );
 
       CPPUNIT_ASSERT( grid.getSpaceSteps().x() == 0.1 );
@@ -241,10 +241,10 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
       GridType grid;
       grid.setDimensions( xSize, ySize, zSize );
  
-      typedef typename GridType::template MeshEntity< 0 > VertexType;
-      typedef typename VertexType::EntityOrientationType OrientationType;
-      typedef typename VertexType::EntityBasisType BasisType;
-      VertexType vertex( grid );
+      typedef typename GridType::template MeshEntity< 0 > PointType;
+      typedef typename PointType::EntityOrientationType OrientationType;
+      typedef typename PointType::EntityBasisType BasisType;
+      PointType vertex( grid );
  
       for( vertex.getCoordinates().z() = 0;
            vertex.getCoordinates().z() < zSize + 1;
@@ -291,43 +291,43 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( -1, 0, 0 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< -1, 0, 0 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< -1, 0, 0 >() ) );
                }
                if( cell.getCoordinates().x() < xSize - 1 )
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 1, 0, 0 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 1, 0, 0 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 1, 0, 0 >() ) );
                }
                if( cell.getCoordinates().y() > 0 )
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, -1, 0 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, -1, 0 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, -1, 0 >() ) );
                }
                if( cell.getCoordinates().y() < ySize - 1 )
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, 1, 0 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, 1, 0 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, 1, 0 >() ) );
                }
                if( cell.getCoordinates().z() > 0 )
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, 0, -1 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, 0, -1 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, 0, -1 >() ) );
                }
                if( cell.getCoordinates().z() < zSize - 1 )
                {
                   CellType auxCell( grid, cell.getCoordinates() + CoordinatesType( 0, 0, 1 ) );
                   const IndexType auxCellIndex = grid.getEntityIndex( auxCell );
-                  auto neighbourEntities = cell.getNeighbourEntities();
-                  CPPUNIT_ASSERT( ( auxCellIndex == neighbourEntities.template getEntityIndex< 0, 0, 1 >() ) );
+                  auto neighborEntities = cell.getNeighborEntities();
+                  CPPUNIT_ASSERT( ( auxCellIndex == neighborEntities.template getEntityIndex< 0, 0, 1 >() ) );
                }
             }
    }
@@ -357,44 +357,44 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
             {
                //const IndexType cellIndex = grid.getEntityIndex( cell );
                cell.refresh();//setIndex( cellIndex );
-               auto neighbourEntities = cell.template getNeighbourEntities< GridType::Face::entityDimensions >();
+               auto neighborEntities = cell.template getNeighborEntities< GridType::Face::entityDimension >();
  
 
                face.setCoordinates( cell.getCoordinates() );
                face.setOrientation( EntityOrientationType( 1, 0, 0 ) );
                //CoordinatesType faceCoordinates( i, j, k );
                IndexType faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< -1, 0, 0 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< -1, 0, 0 >() ) );
 
                //faceCoordinates = CoordinatesType( i + 1, j, k );
                face.setCoordinates( cell.getCoordinates() + CoordinatesType( 1, 0, 0 ) );
                face.setOrientation( EntityOrientationType( 1, 0 , 0 ) );
                faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< 1, 0, 0 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< 1, 0, 0 >() ) );
 
                //faceCoordinates = CoordinatesType( i, j, k );
                face.setCoordinates( cell.getCoordinates() );
                face.setOrientation( EntityOrientationType( 0, -1, 0 ) );
                faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< 0, -1, 0 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< 0, -1, 0 >() ) );
 
                //faceCoordinates = CoordinatesType( i, j + 1, k );
                face.setCoordinates( cell.getCoordinates() + CoordinatesType( 0, 1, 0 ) );
                face.setOrientation( EntityOrientationType( 0, 1, 0 ) );
                faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< 0, 1, 0 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< 0, 1, 0 >() ) );
 
                //faceCoordinates = CoordinatesType( i, j, k );
                face.setCoordinates( cell.getCoordinates() );
                face.setOrientation( EntityOrientationType( 0, 0, -1 ) );
                faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< 0, 0, -1 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< 0, 0, -1 >() ) );
 
                //faceCoordinates = CoordinatesType( i, j, k + 1 );
                face.setCoordinates( cell.getCoordinates() + CoordinatesType( 0, 0, 1 ) );
                face.setOrientation( EntityOrientationType( 0, 0, 1 ) );
                faceIndex = grid.getEntityIndex( face );
-               CPPUNIT_ASSERT( ( faceIndex == neighbourEntities.template getEntityIndex< 0, 0, 1 >() ) );
+               CPPUNIT_ASSERT( ( faceIndex == neighborEntities.template getEntityIndex< 0, 0, 1 >() ) );
             }
    }
 
@@ -428,20 +428,20 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
                   face.setOrientation( EntityOrientationType( 1, 0, 0  ) );
                   //const IndexType faceIndex = grid.getEntityIndex( face );
                   face.refresh();//setIndex( faceIndex );
-                  auto neighbourEntities = face.template getNeighbourEntities< GridType::Cell::entityDimensions >();
+                  auto neighborEntities = face.template getNeighborEntities< GridType::Cell::entityDimension >();
 
 
                   if( face.getCoordinates().x() > 0 )
                   {
                      CellType cell( grid, face.getCoordinates() + CoordinatesType( -1, 0, 0 ) );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< -1, 0, 0 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< -1, 0, 0 >() ) );
                   }
                   if( face.getCoordinates().x() < xSize )
                   {
                      CellType cell( grid, face.getCoordinates() );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< 1, 0, 0 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< 1, 0, 0 >() ) );
                   }
                }
                if( face.getCoordinates().x() < xSize && face.getCoordinates().z() < zSize )
@@ -449,19 +449,19 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
                   face.setOrientation( EntityOrientationType( 0, 1, 0  ) );
                   //const IndexType faceIndex = grid.getEntityIndex( face );
                   face.refresh();//setIndex( faceIndex );
-                  auto neighbourEntities = face.template getNeighbourEntities< GridType::Cell::entityDimensions >();
+                  auto neighborEntities = face.template getNeighborEntities< GridType::Cell::entityDimension >();
  
                   if( face.getCoordinates().y() > 0 )
                   {
                      CellType cell( grid, face.getCoordinates() + CoordinatesType( 0, -1, 0 ) );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< 0, -1, 0 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< 0, -1, 0 >() ) );
                   }
                   if( face.getCoordinates().y() < ySize )
                   {
                      CellType cell( grid, face.getCoordinates() );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< 0, 1, 0 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< 0, 1, 0 >() ) );
                   }
                }
                if( face.getCoordinates().x() < xSize && face.getCoordinates().y() < ySize )
@@ -469,19 +469,19 @@ class GridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCase
                   face.setOrientation( EntityOrientationType( 0, 0, 1  ) );
                   //const IndexType faceIndex = grid.getEntityIndex( face );
                   face.refresh();//setIndex( faceIndex );
-                  auto neighbourEntities = face.template getNeighbourEntities< GridType::Cell::entityDimensions >();
+                  auto neighborEntities = face.template getNeighborEntities< GridType::Cell::entityDimension >();
  
                   if( face.getCoordinates().z() > 0 )
                   {
                      CellType cell( grid, face.getCoordinates() + CoordinatesType( 0, 0, -1 ) );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< 0, 0, -1 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< 0, 0, -1 >() ) );
                   }
                   if( face.getCoordinates().z() < zSize )
                   {
                      CellType cell( grid, face.getCoordinates() );
                      IndexType cellIndex = grid.getEntityIndex( cell );
-                     CPPUNIT_ASSERT( ( cellIndex == neighbourEntities.template getEntityIndex< 0, 0, 1 >() ) );
+                     CPPUNIT_ASSERT( ( cellIndex == neighborEntities.template getEntityIndex< 0, 0, 1 >() ) );
                   }
                }
             }
diff --git a/tests/unit-tests/mesh/tnlGridTester.h b/tests/unit-tests/mesh/tnlGridTester.h
index ed0bf311997508415bb7ce6ea19b7a2a05e280f0..da49138ad2d7b4989d37d7b1e5f5c01150119705 100644
--- a/tests/unit-tests/mesh/tnlGridTester.h
+++ b/tests/unit-tests/mesh/tnlGridTester.h
@@ -20,7 +20,7 @@
 #include <TNL/Meshes/Grid.h>
 
 
-template< int Dimensions, typename RealType, typename Device, typename IndexType >
+template< int Dimension, typename RealType, typename Device, typename IndexType >
 class GridTester{};
 
 #include "tnlGrid1DTester.h"
diff --git a/tests/unit-tests/mesh/tnlMeshEntityTester.h b/tests/unit-tests/mesh/tnlMeshEntityTester.h
index 0a9797dfc060378c20a2852b5565e86764b2177f..a62dd4eefeb73154a114a0491783cf2f9a6e300b 100644
--- a/tests/unit-tests/mesh/tnlMeshEntityTester.h
+++ b/tests/unit-tests/mesh/tnlMeshEntityTester.h
@@ -35,13 +35,13 @@ class TestTriangleMeshConfig : public MeshConfigBase< MeshTriangleTopology >
    public:
  
       template< typename MeshEntity >
-      static constexpr bool subentityStorage( MeshEntity entity, int subentityDimensions )
+      static constexpr bool subentityStorage( MeshEntity entity, int subentityDimension )
       {
          return true;
       }
  
       template< typename MeshEntity >
-      static constexpr bool superentityStorage( MeshEntity entity, int superentityDimensions )
+      static constexpr bool superentityStorage( MeshEntity entity, int superentityDimension )
       {
          return true;
       }
@@ -52,13 +52,13 @@ class TestTetrahedronMeshConfig : public MeshConfigBase< MeshTetrahedronTopology
    public:
  
       template< typename MeshEntity >
-      static constexpr bool subentityStorage( MeshEntity entity, int subentityDimensions )
+      static constexpr bool subentityStorage( MeshEntity entity, int subentityDimension )
       {
          return true;
       }
  
       template< typename MeshEntity >
-      static constexpr bool superentityStorage( MeshEntity entity, int superentityDimensions )
+      static constexpr bool superentityStorage( MeshEntity entity, int superentityDimension )
       {
          return true;
       }
diff --git a/tests/unit-tests/mesh/tnlMeshTester.h b/tests/unit-tests/mesh/tnlMeshTester.h
index 9c5c72074d12b830867e25b6eb80f062fe0b4d28..39aaaf43d79776ecc2ae756ffa97005d0c45363f 100644
--- a/tests/unit-tests/mesh/tnlMeshTester.h
+++ b/tests/unit-tests/mesh/tnlMeshTester.h
@@ -37,9 +37,9 @@ class TestTriangleMeshConfig : public MeshConfigBase< MeshTriangleTopology >
    public:
 
       static constexpr bool entityStorage( int dimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; };
-      //template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimension ) { return true; };
+      //template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimension ) { return true; };
+      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimension ) { return true; };
 };
 
 class TestQuadrilateralMeshConfig : public MeshConfigBase< MeshQuadrilateralTopology >
@@ -47,9 +47,9 @@ class TestQuadrilateralMeshConfig : public MeshConfigBase< MeshQuadrilateralTopo
    public:
  
       static constexpr bool entityStorage( int dimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) { return ( SubentityDimensions % 2 != 0 ); };
-      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimension ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimension ) { return ( SubentityDimension % 2 != 0 ); };
+      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimension ) { return true; };
 };
 
 class TestTetrahedronMeshConfig : public MeshConfigBase< MeshTetrahedronTopology >
@@ -57,9 +57,9 @@ class TestTetrahedronMeshConfig : public MeshConfigBase< MeshTetrahedronTopology
    public:
 
       static constexpr bool entityStorage( int dimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) {  return ( SubentityDimensions % 2 != 0 ); };
-      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimension ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimension ) {  return ( SubentityDimension % 2 != 0 ); };
+      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimension ) { return true; };
 };
 
 class TestHexahedronMeshConfig : public MeshConfigBase< MeshHexahedronTopology >
@@ -67,9 +67,9 @@ class TestHexahedronMeshConfig : public MeshConfigBase< MeshHexahedronTopology >
    public:
 
       static constexpr bool entityStorage( int dimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimensions ) { return true; };
-      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimensions ) {  return ( SubentityDimensions % 2 != 0 ); };
-      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimensions ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityStorage( MeshEntity, int SubentityDimension ) { return true; };
+      template< typename MeshEntity > static constexpr bool subentityOrientationStorage( MeshEntity, int SubentityDimension ) {  return ( SubentityDimension % 2 != 0 ); };
+      template< typename MeshEntity > static constexpr bool superentityStorage( MeshEntity, int SuperentityDimension ) { return true; };
 };
 
 template< typename RealType, typename Device, typename IndexType >
diff --git a/tests/unit-tests/operators/CMakeLists.txt b/tests/unit-tests/operators/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/operators/diffusion/CMakeLists.txt b/tests/unit-tests/operators/diffusion/CMakeLists.txt
index 5ad9a0af6f04b4798a5075bd6cd22b6191dd05a0..5d09ac10a1aeb9daca61a35f5075c8b60c1fad5d 100644
--- a/tests/unit-tests/operators/diffusion/CMakeLists.txt
+++ b/tests/unit-tests/operators/diffusion/CMakeLists.txt
@@ -10,8 +10,7 @@ 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
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   CUDA_ADD_EXECUTABLE( tnlOneSidedMeanCurvatureTest-cuda${mpiExt}${debugExt} ${headers} tnlOneSidedMeanCurvatureTest.cu )
    TARGET_LINK_LIBRARIES( tnlOneSidedMeanCurvatureTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
 
diff --git a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h
index 0416a13739a174cc34b98680af4a455d10804ae1..5d7c110553e2c528944b4c2256624ef69347a80b 100644
--- a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h
+++ b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h
@@ -67,8 +67,8 @@ class LinearDiffusionTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, eoc, tolerance, verbose );
       }
  
@@ -103,7 +103,7 @@ template< typename Mesh,
           bool verbose >
 bool setTestFunction()
 {
-   return runTest< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimensions(), double >, write, verbose >();
+   return runTest< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimension(), double >, write, verbose >();
 }
 
 template< typename Device,
diff --git a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
index 42e24d21df3ab0700d12d95df2432df93d6a9545..b86372509e4dd4d233ff5f30f0da69ab5d3917c0 100644
--- a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
+++ b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
@@ -73,8 +73,8 @@ class OneSidedMeanCurvatureTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, eoc, tolerance, verbose );
       }
  
@@ -109,7 +109,7 @@ template< typename Mesh,
           bool verbose >
 bool setTestFunction()
 {
-   return runTest< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimensions(), double >, write, verbose >();
+   return runTest< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimension(), double >, write, verbose >();
 }
 
 template< typename Device,
diff --git a/tests/unit-tests/operators/fdm/CMakeLists.txt b/tests/unit-tests/operators/fdm/CMakeLists.txt
old mode 100755
new mode 100644
index a85d068b485abd21f1c29e27746c722684d9929e..ad2395de3c40fc3c5c49221a1b023e744f74fceb
--- a/tests/unit-tests/operators/fdm/CMakeLists.txt
+++ b/tests/unit-tests/operators/fdm/CMakeLists.txt
@@ -3,8 +3,7 @@ TARGET_LINK_LIBRARIES( tnlFiniteDifferencesTest${mpiExt}${debugExt} ${CPPUNIT_LI
                                                                  tnl${mpiExt}${debugExt}-0.1 )
 
 if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlFiniteDifferencesTest-cuda${mpiExt}${debugExt} ${headers} tnlFiniteDifferencesTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   CUDA_ADD_EXECUTABLE( tnlFiniteDifferencesTest-cuda${mpiExt}${debugExt} ${headers} tnlFiniteDifferencesTest.cu )
    TARGET_LINK_LIBRARIES( tnlFiniteDifferencesTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
 endif()                                                                      
diff --git a/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h
index b5cb4817da17090f55cd537142d2aab4493322c1..7e401899a67fd9be56acdaef120888b0528e2721 100644
--- a/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h
+++ b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h
@@ -97,8 +97,8 @@ class tnlFiniteDifferenceTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );
       }
  
@@ -160,8 +160,8 @@ template< typename Mesh,
           bool Verbose >
 bool setFunction()
 {
-    const int Dimensions = Mesh::meshDimensions;
-    typedef Functions::Analytic::ExpBump< Dimensions, RealType >  Function;
+    const int Dimension = Mesh::meshDimension;
+    typedef Functions::Analytic::ExpBump< Dimension, RealType >  Function;
     return setFiniteDifferenceOperator< Mesh, Function, RealType, IndexType, XDifference, YDifference, ZDifference, MeshSize, WriteFunctions, Verbose  >();
 }
 
diff --git a/tests/unit-tests/operators/geometric/CMakeLists.txt b/tests/unit-tests/operators/geometric/CMakeLists.txt
index 71d62e19415fc60329923ad0e8a8247c82286800..dac9802609b798141ae4c1ed7fbc8b5ce01f088e 100644
--- a/tests/unit-tests/operators/geometric/CMakeLists.txt
+++ b/tests/unit-tests/operators/geometric/CMakeLists.txt
@@ -11,20 +11,15 @@ TARGET_LINK_LIBRARIES( tnlCoFVMGradientNormTest${mpiExt}${debugExt} ${CPPUNIT_LI
                                                                  tnl${mpiExt}${debugExt}-0.1 )
 
 if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlFDMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlFDMGradientNormTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   CUDA_ADD_EXECUTABLE( tnlFDMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlFDMGradientNormTest.cu )
    TARGET_LINK_LIBRARIES( tnlFDMGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
    
-   CUDA_ADD_EXECUTABLE( tnlTwoSidedGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlTwoSidedGradientNormTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   CUDA_ADD_EXECUTABLE( tnlTwoSidedGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlTwoSidedGradientNormTest.cu )
    TARGET_LINK_LIBRARIES( tnlTwoSidedGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
 
-   CUDA_ADD_EXECUTABLE( tnlCoFVMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlCoFVMGradientNormTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   CUDA_ADD_EXECUTABLE( tnlCoFVMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlCoFVMGradientNormTest.cu )
    TARGET_LINK_LIBRARIES( tnlCoFVMGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
-
 endif()                                                                      
-
diff --git a/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h
index 0553b6df2812db2318d03d5dfd2ff4c45ec9b119..9b84c08fc310c7e525dffc08fefd0f68f14d292f 100644
--- a/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h
+++ b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h
@@ -75,8 +75,8 @@ class CoFVMGradientNormTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );
       }
  
@@ -115,7 +115,7 @@ template< typename Mesh,
           bool verbose >
 bool setTestFunction()
 {
-   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimensions(), double >, write, verbose >();
+   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimension(), double >, write, verbose >();
 }
 
 template< typename Device,
diff --git a/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h
index 1be915a7cb9058d7104698cb35d42d1379846d8c..7a47af33c8ea42da3ef977dfbb7a659c2c3265d5 100644
--- a/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h
+++ b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h
@@ -89,8 +89,8 @@ class FDMGradientNormTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );
       }
  
@@ -135,7 +135,7 @@ template< typename Mesh,
           bool verbose >
 bool setTestFunction()
 {
-   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimensions(), double >, write, verbose >();
+   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimension(), double >, write, verbose >();
 }
 
 template< typename Device,
diff --git a/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h
index 045daa55f7604363fa7a3880525b3bbf9dc722ef..d32193ccffb45d79cab4dd5d4be58f4ab9538262 100644
--- a/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h
+++ b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h
@@ -66,8 +66,8 @@ class TwoSidedGradientNormTest
       void runUnitTest()
       {
          RealType coarseErrors[ 3 ], fineErrors[ 3 ];
-         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
-         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimension() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimension() - 1 ], fineErrors );
          this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );
       }
  
@@ -109,7 +109,7 @@ template< typename Mesh,
           bool verbose >
 bool setTestFunction()
 {
-   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimensions(), double >, write, verbose >();
+   return setDifferenceOperator< Mesh, Functions::Analytic::ExpBump< Mesh::getMeshDimension(), double >, write, verbose >();
 }
 
 template< typename Device,
diff --git a/tests/unit-tests/operators/tnlApproximationError.h b/tests/unit-tests/operators/tnlApproximationError.h
index a61f5128ffbe3da8c8b3ab047ba0cb93f9d0511c..fcbf8404275f9be76d78fb4f3b9ef574dce3e46f 100644
--- a/tests/unit-tests/operators/tnlApproximationError.h
+++ b/tests/unit-tests/operators/tnlApproximationError.h
@@ -33,9 +33,9 @@ class tnlApproximationError
       typedef typename ApproximateOperator::MeshType MeshType;
       typedef typename MeshType::DeviceType DeviceType;
       typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef SharedPointer< MeshType > MeshPointer;
-      typedef Functions::Analytic::Constant< MeshType::meshDimensions, RealType > ConstantType;
+      typedef Functions::Analytic::Constant< MeshType::meshDimension, RealType > ConstantType;
       typedef Operators::DirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
 
       static void getError( const ExactOperator& exactOperator,
@@ -48,7 +48,7 @@ class tnlApproximationError
                             bool writeFunctions )
       {
          typedef Functions::MeshFunction< MeshType, MeshEntity::getDimensions() > MeshFunction;
-         typedef Operators::DirichletBoundaryConditions< MeshType, Functions::Analytic::Constant< MeshType::meshDimensions > > DirichletBoundaryConditions;
+         typedef Operators::DirichletBoundaryConditions< MeshType, Functions::Analytic::Constant< MeshType::meshDimension > > DirichletBoundaryConditions;
          typedef Functions::OperatorFunction< DirichletBoundaryConditions, MeshFunction > BoundaryOperatorFunction;
          typedef Functions::OperatorFunction< ApproximateOperator, MeshFunction > OperatorFunction;
          typedef Functions::ExactOperatorFunction< ExactOperator, Function > ExactOperatorFunction;
@@ -61,11 +61,11 @@ class tnlApproximationError
 
          String meshSizeString( meshPointer->getDimensions().x() );
          String dimensionsString;
-         if( MeshType::getMeshDimensions() == 1 )
+         if( MeshType::getMeshDimension() == 1 )
             dimensionsString = "1D-";
-         if( MeshType::getMeshDimensions() == 2 )
+         if( MeshType::getMeshDimension() == 2 )
             dimensionsString = "2D-";
-         if( MeshType::getMeshDimensions() == 3 )
+         if( MeshType::getMeshDimension() == 3 )
             dimensionsString = "3D-";
 
          //if( writeFunctions )
@@ -117,8 +117,8 @@ class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function,
       typedef Mesh MeshType;
       typedef typename MeshType::DeviceType DeviceType;
       typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::VertexType VertexType;
-      typedef Constant< MeshType::meshDimensions, RealType > ConstantType;
+      typedef typename MeshType::PointType PointType;
+      typedef Constant< MeshType::meshDimension, RealType > ConstantType;
       typedef DirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
 
       static void getError( const Mesh& mesh,
diff --git a/tests/unit-tests/operators/tnlOperatorCompositionTest.h b/tests/unit-tests/operators/tnlOperatorCompositionTest.h
index f872c323ff75c828e527ff82df5ce791231c51d3..0a380191e4ac0c5806eedbc8e60a4ad846c83960 100644
--- a/tests/unit-tests/operators/tnlOperatorCompositionTest.h
+++ b/tests/unit-tests/operators/tnlOperatorCompositionTest.h
@@ -40,12 +40,12 @@ class OperatorCompositionTest
    typedef typename OperatorType::RealType RealType;
    typedef typename OperatorType::IndexType IndexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
-   typedef typename MeshType::VertexType VertexType;
-   typedef Functions::Analytic::ExpBump< MeshType::getMeshDimensions(), typename MeshType::RealType > TestFunctionType;
-   typedef Functions::Analytic::Constant< MeshType::getMeshDimensions(), typename MeshType::RealType > Constant;
+   typedef typename MeshType::PointType PointType;
+   typedef Functions::Analytic::ExpBump< MeshType::getMeshDimension(), typename MeshType::RealType > TestFunctionType;
+   typedef Functions::Analytic::Constant< MeshType::getMeshDimension(), typename MeshType::RealType > Constant;
    typedef Operators::NeumannBoundaryConditions< MeshType, Constant > BoundaryConditions;
    typedef Operators::OperatorComposition< OperatorType, OperatorType, BoundaryConditions > OperatorComposition;
-   typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimensions() > MeshFunctionType;
+   typedef Functions::MeshFunction< MeshType, MeshType::getMeshDimension() > MeshFunctionType;
    typedef Functions::OperatorFunction< OperatorType, MeshFunctionType, BoundaryConditions > OperatorFunction;
    typedef Functions::OperatorFunction< OperatorType, OperatorFunction, BoundaryConditions > OperatorFunction2;
 
@@ -67,7 +67,7 @@ class OperatorCompositionTest
    {      
       SharedPointer< MeshType > mesh;
       mesh->setDimensions( CoordinatesType( 25 ) );
-      mesh->setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      mesh->setDomain( PointType( -1.0 ), PointType( 2.0 ) );
       TestFunctionType testFunction;
       testFunction.setAmplitude( 1.0 );
       testFunction.setSigma( 1.0 );
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h
index d7e733892c999db690a627070799f51c36db23cf..6a540aa61dfbf55d0e3014ed46cecb139043eea3 100644
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h
@@ -20,15 +20,15 @@ class tnlPDEOperatorEocTestFunctionSetter
 {
 };
 
-template< int Dimensions,
+template< int Dimension,
           typename Real >
-class tnlPDEOperatorEocTestFunctionSetter< Functions::Analytic::ExpBump< Dimensions, Real > >
+class tnlPDEOperatorEocTestFunctionSetter< Functions::Analytic::ExpBump< Dimension, Real > >
 {
-   static_assert( Dimensions >= 0 && Dimensions <= 3,
-      "Wrong parameter Dimensions." );
+   static_assert( Dimension >= 0 && Dimension <= 3,
+      "Wrong parameter Dimension." );
    public:
  
-      typedef Functions::Analytic::ExpBump< Dimensions, Real > FunctionType;
+      typedef Functions::Analytic::ExpBump< Dimension, Real > FunctionType;
  
       static void setup( FunctionType& function )
       {
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h
index 9f983e5483c82d0cdb1fc7accdcebb1a3b93a234..4c96be678bd5372772346d8db77e5ae70157a7dd 100644
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h
@@ -28,7 +28,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 1, Real, Device, Index > >
    public:
  
       typedef Meshes::Grid< 1, Real, Device, Index > MeshType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
@@ -36,7 +36,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 1, Real, Device, Index > >
  
       static bool setup( MeshType& mesh, const IndexType meshSize )
       {
-         VertexType origin, proportions;
+         PointType origin, proportions;
          origin.x() = -2.0;
          proportions.x() = 4.0;
          mesh.setDomain( origin, proportions );
@@ -57,7 +57,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 2, Real, Device, Index > >
    public:
  
       typedef Meshes::Grid< 2, Real, Device, Index > MeshType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
@@ -65,7 +65,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 2, Real, Device, Index > >
  
       static bool setup( MeshType& mesh, const IndexType meshSize )
       {
-         VertexType origin, proportions;
+         PointType origin, proportions;
          origin.x() = -1.0;
          origin.y() = -1.0;
          proportions.x() = 2.0;
@@ -89,7 +89,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 3, Real, Device, Index > >
    public:
  
       typedef Meshes::Grid< 3, Real, Device, Index > MeshType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
@@ -97,7 +97,7 @@ class tnlPDEOperatorEocTestMeshSetter< Meshes::Grid< 3, Real, Device, Index > >
 
       static bool setup( MeshType& mesh, const IndexType meshSize )
       {
-         VertexType origin, proportions;
+         PointType origin, proportions;
          origin.x() = -1.0;
          origin.y() = -1.0;
          origin.z() = -1.0;
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
index f6d37712a172528ce33d17d58a9aa254e66d30e8..fea04bbe33de7b1eba90fc06e73a1eab971ff17b 100644
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
@@ -41,14 +41,14 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
       typedef Meshes::Grid< 1, Real, Device, Index > MeshType;
       typedef ExactOperator ExactOperatorType;
       typedef ApproximateOperator ApproximateOperatorType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef ExpBump< 1, Real > FunctionType;
 
    static void setMesh( MeshType& mesh,
                         const IndexType& size )
    {
-      VertexType origin, proportions;
+      PointType origin, proportions;
       origin.x() = -2.0;
       proportions.x() = 4.0;
       mesh.setDomain( origin, proportions );
@@ -82,14 +82,14 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
       typedef Meshes::Grid< 2, Real, Device, Index > MeshType;
       typedef ExactOperator ExactOperatorType;
       typedef ApproximateOperator ApproximateOperatorType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef ExpBump< 2, Real > FunctionType;
 
    static void setMesh( MeshType& mesh,
                         const IndexType& size )
    {
-      VertexType origin, proportions;
+      PointType origin, proportions;
       origin.x() = -1.0;
       origin.y() = -1.0;
       proportions.x() = 2.0;
@@ -126,14 +126,14 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
       typedef Meshes::Grid< 3, Real, Device, Index > MeshType;
       typedef ExactOperator ExactOperatorType;
       typedef ApproximateOperator ApproximateOperatorType;
-      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::PointType PointType;
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef ExpBump< 3, Real > FunctionType;
 
    static void setMesh( MeshType& mesh,
                         const IndexType& size )
    {
-      VertexType origin, proportions;
+      PointType origin, proportions;
       origin.x() = -1.0;
       origin.y() = -1.0;
       origin.z() = -1.0;
diff --git a/tests/unit-tests/solver/CMakeLists.txt b/tests/unit-tests/solver/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/solver/pde/CMakeLists.txt b/tests/unit-tests/solver/pde/CMakeLists.txt
old mode 100755
new mode 100644
diff --git a/tests/unit-tests/solver/tnlMersonSolverTester.h b/tests/unit-tests/solver/tnlMersonSolverTester.h
index 838da12e964de24f13276888252bbbb9a99f2ad4..f158a62515b2b28b107f5c1b9521b4e4094bce81 100644
--- a/tests/unit-tests/solver/tnlMersonSolverTester.h
+++ b/tests/unit-tests/solver/tnlMersonSolverTester.h
@@ -99,7 +99,7 @@ class MersonTester : public CppUnit :: TestCase
       return suiteOfTests;
    };
 
-   void GetExplicitRHS( const Real& time,
+   void getExplicitUpdate( const Real& time,
                         GridOld< 2, Real, Devices::Host, int >& u,
                         GridOld< 2, Real, Devices::Host, int >& fu )
    {
@@ -115,7 +115,7 @@ class MersonTester : public CppUnit :: TestCase
          }
    }
 
-   void GetExplicitRHS( const Real& time,
+   void getExplicitUpdate( const Real& time,
                         GridOld< 2, Real, Devices::Cuda, int >& u,
                         GridOld< 2, Real, Devices::Cuda, int >& fu )
    {
diff --git a/tests/unit-tests/solver/tnlSolverTester.h b/tests/unit-tests/solver/tnlSolverTester.h
index 05bc787b065acea7fa206a8c8350f773ead8d33c..62c489727c432fe6f9f1c1c3171aa7b2ee8a316c 100644
--- a/tests/unit-tests/solver/tnlSolverTester.h
+++ b/tests/unit-tests/solver/tnlSolverTester.h
@@ -52,7 +52,7 @@ class SolverTesterProblem
 
    DofVectorType& getDofVector() { return this->dofVector;};
 
-   void GetExplicitRHS( const RealType& time,
+   void getExplicitUpdate( const RealType& time,
                         const RealType& tau,
                         DofVectorType& _u,
                         DofVectorType& _fu ){};