diff --git a/CMakeLists.txt b/CMakeLists.txt
index b215cce5d76251005d880a2d9a5e25531ac689c8..61a85bf4637f99157c7762b69e9d884edf90b874 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -171,6 +171,7 @@ if( WITH_CUDA STREQUAL "yes" )
     endif( CUDA_FOUND )
 endif( WITH_CUDA STREQUAL "yes" )
 
+
 ####
 # Check for OpenMP
 #
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/TODO b/TODO
index e83b80a67e00b0c6fa1911f2d37919b410aa03ba..089a312dd155e7817f8fc5ab5b3a0c823f832be8 100644
--- a/TODO
+++ b/TODO
@@ -16,9 +16,6 @@ TODO:
 
 
 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
@@ -31,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/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 0f00654e037cfb1ab253fa4276a57fc1f0f25126..dca68ee58a2075836a177be031be115907577cc8 100755
--- 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 46e63b77a2fa7661b8f7dd83cae964eab0c61272..0000000000000000000000000000000000000000
--- a/examples/advection/LaxFridrichs.h
+++ /dev/null
@@ -1,222 +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;
-      Real advectionSpeedX;
-      Real advectionSpeedY;
-
-      void setAdvectionSpeedY(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedY = advectionSpeed;
-      }
-
-
-      void setAdvectionSpeedX(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedX = advectionSpeed;
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static 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;
-      Real advectionSpeedX;
-      Real advectionSpeedY;
-
-      void setAdvectionSpeedY(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedY = advectionSpeed;
-      }
-
-
-      void setAdvectionSpeedX(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedX = advectionSpeed;
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static 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;
-      Real advectionSpeedX;
-      Real advectionSpeedY;
-
-      void setAdvectionSpeedY(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedY = advectionSpeed;
-      }
-
-
-      void setAdvectionSpeedX(const Real& advectionSpeed)
-      {
-	   this->advectionSpeedX = advectionSpeed;
-      }
-
-      void setViscosity(const Real& artificalViscosity)
-      {
-	   this->artificalViscosity = artificalViscosity;
-      }
-      
-      void setTau(const Real& tau)
-      {
-          this->tau = tau;
-      };
-
-      static 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 dc65664b3b5b8ef599d61988924b3a705b6f94ca..0000000000000000000000000000000000000000
--- a/examples/advection/LaxFridrichs_impl.h
+++ /dev/null
@@ -1,361 +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 >(); 
-   double a;
-   a = this->advectionSpeedX;
-   return   (0.5 / this->tau ) * this->artificalViscosity *
-	    ( u[ west ]- 2.0 * u[ center ] + u[ east ] )
-            - (a = this->advectionSpeedX * ( u[ east ] - u[west] ) ) * hxInverse * 0.5;
-
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< 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 >(); 
-   double a;
-   double b;
-   a = this->advectionSpeedX;
-   b = this->advectionSpeedY;
-   return ( 0.25 / this->tau ) * this->artificalViscosity * 
-          ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4 * u[ center ] ) -
-          (a * ( u[ east ] - u[west] ) ) * hxInverse * 0.5 - 
-          (b * ( u[ north ] - u[ south ] ) ) * hyInverse * 0.5;
-
-
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< 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& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
-   const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
-   const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -2 >(); 
-   const IndexType& center = entity.getIndex(); 
-   const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0,  0 >(); 
-   const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0,  0 >(); 
-   const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >(); 
-   const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >(); 
-   const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >(); 
-   const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >(); 
-   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
-          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
-          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichs< 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 dc8d52ae085b277225634637969e72e2d3ff6a40..0000000000000000000000000000000000000000
--- a/examples/advection/advection.h
+++ /dev/null
@@ -1,122 +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"
-
-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.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 >( "sin");
-	    config.addEntryEnum< String >( "sin_square");
-	 config.addEntry< double >( "advection-speedX", "This sets value of advection speed in X direction (default 1)" , 1.0);
-	 config.addEntry< double >( "advection-speedY", "This sets value of advection speed in Y direction (default 1)" , 1.0);
-	 config.addEntry< 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.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 );
-          }
-          typedef Operators::NeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
-          typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-          SolverStarter solverStarter;
-          return solverStarter.template run< Problem >( parameters );
-      }
-
-};
-
-int main( int argc, char* argv[] )
-{
-   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 cd37f52eff7454b863d14eb245b2b9d7236a5a37..0000000000000000000000000000000000000000
--- a/examples/advection/advectionProblem_impl.h
+++ /dev/null
@@ -1,342 +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 )
-{
-   std::cout << "vaules adding";
-   typedef typename MeshType::Cell Cell;
-   int dimensions = parameters.getParameter< int >( "dimension" );
-   int count = mesh->template getEntitiesCount< Cell >();
-   const RealType& size = parameters.getParameter< double >( "realSize" ) / ::pow(count, 1.0/dimensions);
-   const String& beginChoice = parameters.getParameter< String >( "begin" );
-   std::cout << beginChoice << " " << dimensions << "   " << size << "   " << count << "   "<< 1/dimensions << std::endl;
-   getchar();
-   if (beginChoice == "sin_square")
-      {
-	   double constantFunction;
-	   if (dimensions == 1)
-	       {
-                  std::cout << "adding DOFS" << std::endl;
-		   ( *dofs )[0] = 0;
-		   double expValue;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			expValue = std::exp(-std::pow(size*i-2,2));
-			if( (i>0.4*count) && (i<0.5*count))
-                            constantFunction=1;
-                        else
-                            constantFunction=0;
-			if(expValue>constantFunction)
-                           ( *dofs )[i] = expValue;
-                        else ( *dofs )[i] = constantFunction;
-		   };
-		   ( *dofs )[count-1] = 0;
-		}
-	    else if (dimensions == 2)
-	       {
-                   count = std::sqrt(count);
-		   double expValue;
-		   for (IndexType i = 0; i < count-1; i++)
-                      for (IndexType j = 0; j < count-1; j++)
-		      {
-			expValue = std::exp(-std::pow(size*i-2,2)-std::pow(size*j-2,2));
-			if( (i>0.4*count) && (i<0.5*count) && (j>0.4*count) && (j<0.5*count) )
-                           constantFunction=1;
-                        else constantFunction=0;
-			if( expValue>constantFunction)
-                            ( *dofs )[i * count + j] = expValue;
-                        else ( *dofs )[i * count + j] = constantFunction;
-		      };
-		};
-       }
-   else if (beginChoice == "sin")
-      {
-	   if (dimensions == 1)
-	      {
-		   ( *dofs )[0] = 0;
-		   for (IndexType i = 1; i < count-2; i++)
-		   {
-			( *dofs )[i] = std::exp(-std::pow(size*i-2,2));
-		   };
-		   ( *dofs )[count-1] = 0;
-		}
-	    else if (dimensions == 2)
-	       {
-                   count = ::sqrt(count);
-		   for (IndexType i = 1; i < count-1; i++)
-		      for (IndexType j = 1; j < count-1; j++)
-		      {
-			   ( *dofs )[i * count + j] = std::exp(-std::pow(size*i-2,2)-std::pow(size*j-2,2));
-		      };
-		};
-     };
-   //setting velocity field
-   std::cout << *dofs << std::endl;
-   getchar();
-   /*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;*/
-   dofs->save( "dofs.tnl" );
-   this->velocityType = parameters.getParameter< String >( "move" );
-   const double artificalViscosity = parameters.getParameter< double >( "artifical-viscosity" );
-   differentialOperatorPointer->setViscosity(artificalViscosity);
-   const double advectionSpeedX = parameters.getParameter< double >( "advection-speedX" );
-   differentialOperatorPointer->setAdvectionSpeedX(advectionSpeedX);
-   const double advectionSpeedY = parameters.getParameter< double >( "advection-speedY" );
-   differentialOperatorPointer->setAdvectionSpeedY(advectionSpeedY);
-   std::cout << "vaules added";
-   return true;
-}
-
-template< typename Mesh,
-          typename BoundaryCondition,
-          typename RightHandSide,
-          typename DifferentialOperator >
-   template< typename Matrix >
-bool
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-setupLinearSystem( const 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 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
-advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
-getExplicitRHS( 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 >());
-//   const RealType& size = parameters.getParameter< double >( "realSize" ) / ::pow(count, 0.5);
-/*   if (this->velocityType == "rotation")
-   {
-      double radius;
-      for (int i =1; i < count; i++)
-         for (int j =1; j < count; j++)
-            {
-               radius = ::sqrt(pow(i-1-(count/2.0),2) + ::pow(j-1-(count/2.0),2));
-            if (radius != 0.0)
-               _fu[(i-1)*count+j-1] =(0.25*tau)*differentialOperator.artificalViscosity*			//smoothening part
-               (_u[(i-1)*count-2+j]+_u[(i-1)*count+j]+
-               _u[i*count+j-1]+_u[(i-2)*count+j-1]- 
-               4.0*_u[(i-1)*count+j-1])
-               -((1.0/(2.0*count))*differentialOperator.advectionSpeedX						//X addition
-               *radius*(-1)*((j-1-(count/2.0))/radius)
-	       *(_u[(i-1)*count+j]-_u[(i-1)*count+j-2])) 
-	       -((1.0/(2.0*count))*differentialOperator.advectionSpeedY						//Y addition
-               *radius*((i-1-(count/2.0))/radius)
-	       *(_u[i*count+j-1]-_u[(i-2)*count+j-1]))
-            ;}
-  }
-   else if (this->velocityType == "advection")
-*/  { 
-   this->bindDofs( mesh, _u );
-   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 4ce2c6be3f3aea3c49e3619155cc489335bb2e25..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 sin \
-	      --advection-speedX 2.0 \
-
-tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/advection/tnl-run-advection1 b/examples/advection/tnl-run-advection1
deleted file mode 100644
index fb5e81faf2e19ab8e6b19c02c0c441dd96a9c807..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 sin_square \
-	      --advection-speedX 2.0 \
-	      --advection-speedY 2.0 \
-
-tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/advection/tnl-run-advectionrot1 b/examples/advection/tnl-run-advectionrot1
deleted file mode 100644
index 5d3e3990a98ef64233a6b629b4002cc50b26a923..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 sin_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/tnl-heat-equation.h b/examples/heat-equation/tnl-heat-equation.h
index bb9de072e09465d93ba8bacdda947cfc474c1438..382ecdb3ba247c4aa4746b78b4752555f91c6100 100644
--- a/examples/heat-equation/tnl-heat-equation.h
+++ b/examples/heat-equation/tnl-heat-equation.h
@@ -46,7 +46,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");
       };
 };
 
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/EulerPressureGetter.h b/examples/inviscid-flow/1d/EulerPressureGetter.h
deleted file mode 100644
index fc98847a276c165b9352a42767e70e43ec5bcd98..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/EulerPressureGetter.h
+++ /dev/null
@@ -1,63 +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& velocity,
-                           const MeshFunctionType& rhoVel,
-                           const MeshFunctionType& energy,
-                           const RealType& gamma )
-      : rho( rho ), rhoVel( rhoVel ), energy( energy ), gamma( gamma )
-      {}
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const
-      {
-         return this->operator[]( entity.getIndex() );
-      }
-      
-      __cuda_callable__
-      Real operator[]( const IndexType& idx ) const
-      {
-         return ( this->gamma - 1.0 ) * ( this->energy[ idx ] - 0.5 * this->rhoVel[ idx ] * this->rhoVel[ idx ] / this->rho[ idx ]);
-      }
-
-      
-   protected:
-      
-      Real gamma;
-      
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVel;
-      
-      const MeshFunctionType& energy;
-
-};
-
-} //namespace TNL
-
-#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/1d/EulerVelGetter.h b/examples/inviscid-flow/1d/EulerVelGetter.h
deleted file mode 100644
index 7e58ae77d6058d27c6e21169603ed09efe68f089..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/EulerVelGetter.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
-      {
-         return this->rho[ idx ] / this->rhoVel[ idx ];
-      }
-
-      
-   protected:
-      
-      const MeshFunctionType& rho;
-      
-      const MeshFunctionType& rhoVel;
-
-};
-
-} // namespace TNL
-
-#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichs.h b/examples/inviscid-flow/1d/LaxFridrichs.h
deleted file mode 100644
index a5cb7eea5c6183e07facebb0750d02b8fc04d694..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef LaxFridrichs_H
-#define LaxFridrichs_H
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Meshes/Grid.h>
-
-#include "LaxFridrichsContinuity.h"
-#include "LaxFridrichsMomentum.h"
-#include "LaxFridrichsEnergy.h"
-#include "EulerVelGetter.h"
-#include "EulerPressureGetter.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class LaxFridrichs
-{
-   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	/* LaxFridrichs_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity.h
deleted file mode 100644
index 8053895eda0787a52d12335ad4d9a1acc87e114a..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(const MeshFunctionType velocity)
-      {
-          //this->velocity = velocity;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsContinuity< 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(const MeshFunctionType& velocity)
-      {
-	  this->velocity = velocity;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsContinuity< 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(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} // 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 3be1a5b6e4cbcdafcab3cf81c55ac51304123a8e..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h
+++ /dev/null
@@ -1,345 +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[ west ] * this->velocity[ west ] - u[ east ] * this->velocity[ east ] );
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsContinuity< 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 fa0012eb8d006aa452b702c4d0d38eed6b04ccdd..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(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsEnergy< 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(const MeshFunctionType& velocity)
-      {
-	  this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsEnergy< 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(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} // 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 ba8092e807211da1470873252ad269c98d69a990..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[ west ] + this->pressure[ west ] ) * velocity[ west ]  
-          - (u[ east ] + this->pressure[ east ] ) * velocity[ east ] );
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsEnergy< 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 5bb8818833b32f14415c4d2c107dfe0025d44a7e..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(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentum< 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(const MeshFunctionType& velocity)
-      {
-	  this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentum< 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(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} // 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 75c7a7fea080bc13201c19dd843f017b8052e4bc..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h
+++ /dev/null
@@ -1,347 +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[ west ] * this -> velocity[ west ] + this -> pressure [ west ] ) 
-          - (u[ east ] * this -> velocity[ east ] + this -> pressure [ east ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentum< 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/eulerProblem_impl.h b/examples/inviscid-flow/1d/eulerProblem_impl.h
deleted file mode 100644
index 0ed9d4f1a5da37c32faa7fc0e41ef4bc92e84521..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/1d/eulerProblem_impl.h
+++ /dev/null
@@ -1,383 +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 "EulerVelGetter.h"
-#include "EulerPressureGetter.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 CML";
-   typedef typename MeshType::Cell Cell;
-   this->gamma = parameters.getParameter< RealType >( "gamma" );
-   RealType rhoL = parameters.getParameter< RealType >( "left-density" );
-   RealType velL = parameters.getParameter< RealType >( "left-velocity" );
-   RealType preL = parameters.getParameter< RealType >( "left-pressure" );
-   RealType eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * velL * velL;
-   RealType rhoR = parameters.getParameter< RealType >( "right-density" );
-   RealType velR = parameters.getParameter< RealType >( "right-velocity" );
-   RealType preR = parameters.getParameter< RealType >( "right-pressure" );
-   RealType eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * velR * velR;
-   RealType x0 = parameters.getParameter< RealType >( "riemann-border" );
-   std::cout << std::endl << gamma << " " << rhoL << " " << velL << " " << preL << " " << eL << " " << rhoR << " " << velR << " " << preR << " " << eR << " " << x0 << " " << gamma << std::endl;
-   int count = mesh->template getEntitiesCount< Cell >();
-   std::cout << count << std::endl;
-   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 CML"<< 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;
-         };
-   std::cout << "dofs = " << *dofs << std::endl;
-   getchar();
-  
-   
-   /*
-   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 );
-   typedef typename MeshType::Cell Cell;
-   int count = mesh->template getEntitiesCount< Cell >();
-   std::ofstream vysledek;
-/*  std::cout << "pressure:" << std::endl;
-   for (IndexType i = 0; i<count; i++)std::cout << this->pressure[i] << " " << i ;
-      vysledek.open("pressure" + to_string(step) + ".txt");
-   for (IndexType i = 0; i<count; i++)
-      vysledek << 0.01*i << " " << pressure[i] << std::endl;
-   vysledek.close();
-  std::cout << " " << std::endl;
-  std::cout << "velocity:" << std::endl;
-   for (IndexType i = 0; i<count; i++)std::cout << this->velocity[i] << " " ;
-      vysledek.open("velocity" + to_string(step) + ".txt");
-   for (IndexType i = 0; i<count; i++)
-      vysledek << 0.01*i << " " << pressure[i] << std::endl;
-   vysledek.close();
-  std::cout << "energy:" << std::endl;
-   for (IndexType i = 0; i<count; i++)std::cout << this->uEnergy[i] << " " ;
-      vysledek.open("energy" + to_string(step) + ".txt");
-   for (IndexType i = 0; i<count; i++)
-      vysledek << 0.01*i << " " << uEnergy[i] << std::endl;
-   vysledek.close();
-  std::cout << " " << std::endl;
-  std::cout << "density:" << std::endl;
-   for (IndexType i = 0; i<count; i++)std::cout << this->uRho[i] << " " ;
-      vysledek.open("density" + to_string(step) + ".txt");
-   for (IndexType i = 0; i<count; i++)
-      vysledek << 0.01*i << " " << uRho[i] << std::endl;
-   vysledek.close();
-*/   getchar();
-
-   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;
-   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 )
-{
-    std::cout << "explicitRHS" << std::endl;
-    typedef typename MeshType::Cell Cell;
-    int count = mesh->template getEntitiesCount< Cell >();
-	//bind _u
-    this->uRho->bind(mesh, _u, 0);
-    this->uRhoVelocity->bind(mesh, _u ,count);
-    this->uEnergy->bind(mesh, _u, 2 * count);
-		
-	//bind _fu
-    this->fuRho->bind(mesh, _u, 0);
-    this->fuRhoVelocity->bind(mesh, _u, count);
-    this->fuEnergy->bind(mesh, _u, 2 * count);
-
-   //generating Differential operator object
-   SharedPointer< Continuity > lF1DContinuity;
-   SharedPointer< Momentum > lF1DMomentum;
-   SharedPointer< Energy > lF1DEnergy;
-
-   
-   
-   std::cout << "explicitRHSrho" << std::endl;   
-   //rho
-   this->bindDofs( mesh, _u );
-   lF1DContinuity->setTau(tau);
-   lF1DContinuity->setVelocity( *velocity);
-   /*ExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity;
-   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time,
-                                                           mesh,
-                                                           lF1DContinuity,
-                                                           this->boundaryCondition,
-                                                           this->rightHandSide,
-                                                           uRho,
-                                                           fuRho );*/
-
-   std::cout << "explicitRHSrhovel" << std::endl;
-   //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 );
-   
-   std::cout << "explicitRHSenergy" << std::endl;
-   //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;
-}
-
-} // namespace TNL
-
-#endif /* eulerPROBLEM_IMPL_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 a45f664042d2f4dab646319e506dd130b6238cfc..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-constant 0 \
-              --discrete-solver euler \
-              --snapshot-period 0.1 \
-              --final-time 1.0 \
-              --left-density 1.0 \
-              --left-velocity 0.75 \
-              --left-pressure 1.0 \
-              --right-density 0.125 \
-              --right-velocity 0 \
-              --right-pressure 0.1 \
-              --gamma 1.4 \
-              --riemann-border 0.3 \
-
-tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/inviscid-flow/2d/CMakeLists.txt b/examples/inviscid-flow/2d/CMakeLists.txt
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 49e50d72576c270dc1f94f661aae70444ca00677..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerPressureGetter.h
+++ /dev/null
@@ -1,222 +0,0 @@
-#ifndef EulerPressureGetter_H
-#define EulerPressureGetter_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 EulerPressureGetter
-{
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerPressureGetter< 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 gamma;
-      MeshFunctionType velocity;
-      MeshFunctionType rho;
-      MeshFunctionType energy;
-
-      void setGamma(const Real& gamma)
-      {
-          this->gamma = gamma;
-      };
-
-      void setVelocity(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      void setEnergy(const MeshFunctionType& energy)
-      {
-          this->energy = energy;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerPressureGetter< 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 gamma;
-      MeshFunctionType velocity;
-      MeshFunctionType rho;
-      MeshFunctionType energy;
-
-      void setGamma(const Real& gamma)
-      {
-          this->gamma = gamma;
-      };
-
-      void setVelocity(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      void setEnergy(const MeshFunctionType& energy)
-      {
-          this->energy = energy;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerPressureGetter< 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 gamma;
-      MeshFunctionType velocity;
-      MeshFunctionType rho;
-      MeshFunctionType energy;
-
-      void setGamma(const Real& gamma)
-      {
-          this->gamma = gamma;
-      };
-
-      void setVelocity(const MeshFunctionType& velocity)
-      {
-          this->velocity = velocity;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      void setEnergy(const MeshFunctionType& energy)
-      {
-          this->energy = energy;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-
-} //namespace TNL
-
-#include "EulerPressureGetter_impl.h"
-
-#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerPressureGetter_impl.h b/examples/inviscid-flow/2d/EulerPressureGetter_impl.h
deleted file mode 100644
index 7d6b9310df3ddd19fbb261d7eb8dca00b72c82b9..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerPressureGetter_impl.h
+++ /dev/null
@@ -1,338 +0,0 @@
-#ifndef EulerPressureGetter_IMPL_H
-#define EulerPressureGetter_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-EulerPressureGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerPressureGetter< " ) +
-          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
-EulerPressureGetter< 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
-EulerPressureGetter< 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
-EulerPressureGetter< 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
-EulerPressureGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerPressureGetter< " ) +
-          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
-EulerPressureGetter< 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.
-    */
-   //pressure
-   const IndexType& center = entity.getIndex(); 
-
-   return ( this->gamma - 1 ) * ( energy[ center ] - 0.5 * rho[ center ] * ::pow( velocity[ center ],2 ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-EulerPressureGetter< 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
-EulerPressureGetter< 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
-EulerPressureGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerPressureGetter< " ) +
-          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
-EulerPressureGetter< 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
-EulerPressureGetter< 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
-EulerPressureGetter< 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	/* EulerPressureGetterIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/EulerVelGetter.h b/examples/inviscid-flow/2d/EulerVelGetter.h
deleted file mode 100644
index 2da0052b87492d6dd27a2b6def5fa3ead42318fa..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelGetter.h
+++ /dev/null
@@ -1,186 +0,0 @@
-#ifndef EulerVelGetter_H
-#define EulerVelGetter_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 EulerVelGetter
-{
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >
-    : public TNL::Functions::Domain< 1, TNL::Functions::MeshDomain >
-{
-   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();
-      MeshFunctionType velX;
-      MeshFunctionType velY;
-
-      void setVelX(const MeshFunctionType& velX)
-      {
-          this->velX = velX;
-      };
-
-      void setVelY(const MeshFunctionType& velY)
-      {
-          this->velY = velY;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >
-    : public TNL::Functions::Domain< 2, TNL::Functions::MeshDomain >
-{
-   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();
-      MeshFunctionType velX;
-      MeshFunctionType velY;
-
-      void setVelX(const MeshFunctionType& velX)
-      {
-          this->velX = velX;
-      };
-
-      void setVelY(const MeshFunctionType& velY)
-      {
-          this->velY = velY;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >
-    : public TNL::Functions::Domain< 3, TNL::Functions::MeshDomain >
-{
-   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();
-      MeshFunctionType velX;
-      MeshFunctionType velY;
-
-      void setVelX(const MeshFunctionType& velX)
-      {
-          this->velX = velX;
-      };
-
-      void setVelY(const MeshFunctionType& velY)
-      {
-          this->velY = velY;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} //namespace TNL
-
-#include "EulerVelGetter_impl.h"
-
-#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelGetter_impl.h b/examples/inviscid-flow/2d/EulerVelGetter_impl.h
deleted file mode 100644
index eeac07e57011bac7bd9769de63687f2f9bbc0852..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelGetter_impl.h
+++ /dev/null
@@ -1,340 +0,0 @@
-#ifndef EulerVelGetter_IMPL_H
-#define EulerVelGetter_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-EulerVelGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelGetter< " ) +
-          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
-EulerVelGetter< 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
-EulerVelGetter< 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
-EulerVelGetter< 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
-EulerVelGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelGetter< " ) +
-          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
-EulerVelGetter< 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(); 
-   //vel
-   const IndexType& center = entity.getIndex(); 
-   return ::sqrt(pow( velX[ center ],2)+pow( velY[ center ],2));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-EulerVelGetter< 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
-EulerVelGetter< 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
-EulerVelGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelGetter< " ) +
-          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
-EulerVelGetter< 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
-EulerVelGetter< 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
-EulerVelGetter< 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	/* EulerVelGetterIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/EulerVelXGetter.h b/examples/inviscid-flow/2d/EulerVelXGetter.h
deleted file mode 100644
index 93e3363bfab2f2d7eca6b375d9013c661bd47427..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelXGetter.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef EulerVelXGetter_H
-#define EulerVelXGetter_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 EulerVelXGetter
-{
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelXGetter< 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();
-      MeshFunctionType rhoVelX;
-      MeshFunctionType rho;
-
-      void setRhoVelX(const MeshFunctionType& rhoVelX)
-      {
-          this->rhoVelX = rhoVelX;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelXGetter< 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();
-      MeshFunctionType rhoVelX;
-      MeshFunctionType rho;
-
-      void setRhoVelX(const MeshFunctionType& rhoVelX)
-      {
-          this->rhoVelX = rhoVelX;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelXGetter< 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();
-      MeshFunctionType rhoVelX;
-      MeshFunctionType rho;
-
-      void setRhoVelX(const MeshFunctionType& rhoVelX)
-      {
-          this->rhoVelX = rhoVelX;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} // namespace TNL
-
-#include "EulerVelXGetter_impl.h"
-
-#endif	/* EulerVelXGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelXGetter_impl.h b/examples/inviscid-flow/2d/EulerVelXGetter_impl.h
deleted file mode 100644
index 6008509056afbadfbd99dddc3c0a57bad4185b28..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelXGetter_impl.h
+++ /dev/null
@@ -1,339 +0,0 @@
-#pragma once
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-EulerVelXGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelXGetter< " ) +
-          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
-EulerVelXGetter< 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
-EulerVelXGetter< 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
-EulerVelXGetter< 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
-EulerVelXGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelXGetter< " ) +
-          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
-EulerVelXGetter< 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(); 
-   //velX
-   const IndexType& center = entity.getIndex(); 
-   return ( rhoVelX[ center ] / rho[ center ]);
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-EulerVelXGetter< 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
-EulerVelXGetter< 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
-EulerVelXGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelXGetter< " ) +
-          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
-EulerVelXGetter< 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
-EulerVelXGetter< 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
-EulerVelXGetter< 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
-
-
-
diff --git a/examples/inviscid-flow/2d/EulerVelYGetter.h b/examples/inviscid-flow/2d/EulerVelYGetter.h
deleted file mode 100644
index 49474808d38d60baa3a0625ca690b953f714c5c7..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelYGetter.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef EulerVelYGetter_H
-#define EulerVelYGetter_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 EulerVelYGetter
-{
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelYGetter< 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();
-      MeshFunctionType rhoVelY;
-      MeshFunctionType rho;
-
-      void setRhoVelY(const MeshFunctionType& rhoVelY)
-      {
-          this->rhoVelY = rhoVelY;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelYGetter< 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();
-      MeshFunctionType rhoVelY;
-      MeshFunctionType rho;
-
-      void setRhoVelY(const MeshFunctionType& rhoVelY)
-      {
-          this->rhoVelY = rhoVelY;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class EulerVelYGetter< 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();
-      MeshFunctionType rhoVelY;
-      MeshFunctionType rho;
-
-      void setRhoVelY(const MeshFunctionType& rhoVelY)
-      {
-          this->rhoVelY = rhoVelY;
-      };
-
-      void setRho(const MeshFunctionType& rho)
-      {
-          this->rho = rho;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} //namespace TNL
-
-
-#include "EulerVelYGetter_impl.h"
-
-#endif	/* EulerVelYGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelYGetter_impl.h b/examples/inviscid-flow/2d/EulerVelYGetter_impl.h
deleted file mode 100644
index 337f4208c3ee6c0feef0e77e4d136b7704113671..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/EulerVelYGetter_impl.h
+++ /dev/null
@@ -1,332 +0,0 @@
-#ifndef EulerVelYGetter_IMPL_H
-#define EulerVelYGetter_IMPL_H
-
-namespace TNL {
-
-/****
- * 1D problem
- */
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-String
-EulerVelYGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelYGetter< " ) +
-          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
-EulerVelYGetter< 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
-EulerVelYGetter< 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
-EulerVelYGetter< 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
-EulerVelYGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelYGetter< " ) +
-          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
-EulerVelYGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-operator()( const MeshFunction& u,
-            const MeshEntity& entity,
-            const Real& time ) const
-{
-   //velY
-   const IndexType& center = entity.getIndex(); 
-   return ( rhoVelY[ center ] / rho[ center ]);
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-EulerVelYGetter< 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
-EulerVelYGetter< 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
-EulerVelYGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getType()
-{
-   return String( "EulerVelYGetter< " ) +
-          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
-EulerVelYGetter< 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
-EulerVelYGetter< 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
-EulerVelYGetter< 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	/* EulerVelYGetterIMPL_H */
-
diff --git a/examples/inviscid-flow/2d/LaxFridrichs.h b/examples/inviscid-flow/2d/LaxFridrichs.h
deleted file mode 100644
index b689e002122e0c885a53585ebe982f281cfbf43e..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichs.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef LaxFridrichs_H
-#define LaxFridrichs_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 "EulerVelXGetter.h"
-#include "EulerVelYGetter.h"
-#include "EulerVelGetter.h"
-
-namespace TNL {
-
-template< typename Mesh,
-          typename Real = typename Mesh::RealType,
-          typename Index = typename Mesh::IndexType >
-class LaxFridrichs
-{
-   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 EulerVelYGetter< Mesh, Real, Index > VelocityY;
-      typedef EulerVelGetter< Mesh, Real, Index > Velocity;
-      typedef EulerPressureGetter< Mesh, Real, Index > Pressure;
-   
-};
-
-} //namespace TNL
-
-#endif	/* LaxFridrichs_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h b/examples/inviscid-flow/2d/LaxFridrichsContinuity.h
deleted file mode 100644
index 433d6a3512cbd8493ac16d0181d2255bb7692974..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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsContinuity< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsContinuity< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-
-} //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 237b1a5845614a16ec708cf495ad057b297830b2..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 ( 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.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ( u[ west ] * this->velocityX[ west ] - u[ east ] * this->velocityX[ east ] )
-          - 0.5 * hyInverse * ( u[ north ] * this->velocityY[ north ] - u[ south ] * this->velocityY[ east ] );
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsContinuity< 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 8685697295d485d03c57e3748d2b6320e84f3ac5..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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsEnergy< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsEnergy< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} //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 e4f9b2e176d9acdb50157c6cf5f77a6c86801dd8..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.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * ((( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] )
-			      -(( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] ))
-          - 0.5 * hyInverse * ((( u[ north ] + this->pressure[ north ] ) * this->velocityY[ north ] )
-			      -(( u[ south ] + this->pressure[ south ] ) * this->velocityY[ south ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsEnergy< 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 b82758fc7c24cebfcc08580d73c0fd142a82dedc..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h
+++ /dev/null
@@ -1,220 +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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentumX< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentumX< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-
-} // 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 bffb1fe02b4bdc505cb2214954a159f4b8f141bc..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.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hxInverse * (( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] )
-			      -( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] ))
-          - 0.5 * hyInverse * (( u[ north ] * this->velocityY[ north ] )
-			      -( u[ south ] * this->velocityY[ south ] ));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentumX< 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 309051829f7b973ed3009ae12eef2c8ec425f647..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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentumY< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-class LaxFridrichsMomentumY< 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(const MeshFunctionType& velocityX)
-      {
-          this->velocityX = velocityX;
-      };
-
-      void setVelocityY(const MeshFunctionType& velocityY)
-      {
-          this->velocityY = velocityY;
-      };
-
-      void setPressure(const MeshFunctionType& pressure)
-      {
-          this->pressure = pressure;
-      };
-
-      template< typename MeshFunction, typename MeshEntity >
-      __cuda_callable__
-      Real operator()( const MeshFunction& u,
-                       const MeshEntity& entity,
-                       const RealType& time = 0.0 ) const;
-
-      template< typename MeshEntity >
-      __cuda_callable__
-      Index getLinearSystemRowLength( const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity ) const;
-
-      template< typename MeshEntity, typename Vector, typename MatrixRow >
-      __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const RealType& tau,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const MeshEntity& entity,
-                               const MeshFunctionType& u,
-                               Vector& b,
-                               MatrixRow& matrixRow ) const;
-};
-
-} // 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 0624e19aa88750ceb7c78f940b287e515e34ee45..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.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
-          - 0.5 * hyInverse * (( u[ west ] * this->velocityX[ west ] )
-			      -( u[ east ] * this->velocityX[ east ] ))
-          - 0.5 * hxInverse * (( u[ north ] * this->velocityY[ north ] + this->pressure[ north ] )
-			      -( u[ south ] * this->velocityY[ south ] + this->pressure[ south ]));
-}
-
-template< typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Real,
-          typename Index >
-template< typename MeshEntity >
-__cuda_callable__
-Index
-LaxFridrichsMomentumY< 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 a888f928e86227dd3126c32408ba69fe46c89b7d..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/euler.h
+++ /dev/null
@@ -1,118 +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 "LaxFridrichs.h"
-#include "eulerRhs.h"
-#include "eulerBuildConfigTag.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.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
-         config.addEntry< double >( "left-density", "This sets a value of left density." );
-         config.addEntry< double >( "left-velocityX", "This sets a value of left_x velocity." );
-         config.addEntry< double >( "left-velocityY", "This sets a value of left_y velocity." );
-         config.addEntry< double >( "left-pressure", "This sets a value of left pressure." );
-         config.addEntry< double >( "riemann-border", "This sets a position of discontinuity." );
-         config.addEntry< double >( "right-density", "This sets a value of right density." );
-         config.addEntry< double >( "right-velocityX", "This sets a value of right_x velocity." );
-         config.addEntry< double >( "right-velocityY", "This sets a value of right_y velocity." );
-         config.addEntry< double >( "right-pressure", "This sets a value of right pressure." );
-         config.addEntry< double >( "gamma", "This sets a value of gamma constant." );
-
-         /****
-          * Add definition of your solver command line arguments.
-          */
-
-      }
-};
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          typename MeshType,
-          typename ConfigTag,
-          typename SolverStarter >
-class eulerSetter
-{
-   public:
-
-      typedef Real RealType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-
-      static bool run( const Config::ParameterContainer & parameters )
-      {
-          enum { Dimensions = MeshType::getMeshDimensions() };
-          typedef LaxFridrichs< 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 );
-          }
-          typedef Operators::NeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
-          typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
-          SolverStarter solverStarter;
-          return solverStarter.template run< Problem >( parameters );
-      }
-
-};
-
-int main( int argc, char* argv[] )
-{
-   Solvers::Solver< eulerSetter, eulerConfig, BuildConfig > solver;
-   if( ! solver. run( argc, argv ) )
-      return EXIT_FAILURE;
-   return EXIT_SUCCESS;
-}
diff --git a/examples/inviscid-flow/2d/eulerBuildConfigTag.h b/examples/inviscid-flow/2d/eulerBuildConfigTag.h
deleted file mode 100644
index fef4dfffce5400b1ef97786bc92b8a57ac246c1d..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/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 == 2 ) }; };
-
-/****
- * 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 = false }; };
-
-} // namespace Solvers
-} // namespace TNL
-
-#endif /* eulerBUILDCONFIGTAG_H_ */
diff --git a/examples/inviscid-flow/2d/eulerProblem.h b/examples/inviscid-flow/2d/eulerProblem.h
deleted file mode 100644
index 71a9a7a7c1b71f96afd3c289258f27225337f854..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/eulerProblem.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#pragma once
-
-#include <TNL/Problems/PDEProblem.h>
-#include <TNL/Functions/MeshFunction.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 >
-{
-   public:
-
-      typedef typename DifferentialOperator::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;      
-      
-      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::MomentumX MomentumX;
-      typedef typename DifferentialOperator::MomentumY MomentumY;
-      typedef typename DifferentialOperator::Energy Energy;
-      typedef typename DifferentialOperator::Velocity Velocity;
-      typedef typename DifferentialOperator::VelocityX VelocityX;
-      typedef typename DifferentialOperator::VelocityY VelocityY;
-      typedef typename DifferentialOperator::Pressure Pressure;
-
-      static String getTypeStatic();
-
-      String getPrologHeader() const;
-
-      void writeProlog( Logger& logger,
-                        const Config::ParameterContainer& parameters ) const;
-
-      bool setup( const MeshPointer& meshPointer,
-                  const Config::ParameterContainer& parameters,
-                  const String& prefix = "" );
-
-      bool setInitialCondition( const Config::ParameterContainer& parameters,
-                                const MeshPointer& mesh,
-                                DofVectorPointer& dofs,
-                                MeshDependentDataPointer& meshDependentData );
-
-      template< typename Matrix >
-      bool setupLinearSystem( const MeshPointer& mesh,
-                              Matrix& matrix );
-
-      bool makeSnapshot( const RealType& time,
-                         const IndexType& step,
-                         const MeshPointer& mesh,
-                         DofVectorPointer& dofs,
-                         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,
-                           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 boundaryConditionPointer;
-      RightHandSidePointer rightHandSidePointer;
-      
-      //definition
-	   Containers::Vector< RealType, DeviceType, IndexType > _uRho;
-	   Containers::Vector< RealType, DeviceType, IndexType > _uRhoVelocityX;
-	   Containers::Vector< RealType, DeviceType, IndexType > _uRhoVelocityY;
-	   Containers::Vector< RealType, DeviceType, IndexType > _uEnergy;
-
-	   Containers::Vector< RealType, DeviceType, IndexType > _fuRho;
-	   Containers::Vector< RealType, DeviceType, IndexType > _fuRhoVelocityX;
-	   Containers::Vector< RealType, DeviceType, IndexType > _fuRhoVelocityY;
-	   Containers::Vector< RealType, DeviceType, IndexType > _fuEnergy;
-
-      Containers::Vector< RealType, DeviceType, IndexType > rho;
-      Containers::Vector< RealType, DeviceType, IndexType > rhoVelX;
-      Containers::Vector< RealType, DeviceType, IndexType > rhoVelY;
-      Containers::Vector< RealType, DeviceType, IndexType > energy;
-      Containers::Vector< RealType, DeviceType, IndexType > data;
-      Containers::Vector< RealType, DeviceType, IndexType > pressure;
-      Containers::Vector< RealType, DeviceType, IndexType > velocity;
-      Containers::Vector< RealType, DeviceType, IndexType > velocityX;
-      Containers::Vector< RealType, DeviceType, IndexType > velocityY;
-      double gamma;
-
-      
-};
-
-} // namespace TNL
-
-#include "eulerProblem_impl.h"
-
diff --git a/examples/inviscid-flow/2d/eulerRhs.h b/examples/inviscid-flow/2d/eulerRhs.h
deleted file mode 100644
index 1b46dc831fe9daa6133ff32ee4bea5faf4eb8d1c..0000000000000000000000000000000000000000
--- a/examples/inviscid-flow/2d/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/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/CMakeLists.txt b/examples/inviscid-flow/CMakeLists.txt
index 10af3c9c773bc36bca44191359b4a4e244d1faa4..634cce16141410c692254c2b7385b2cac5acd5a7 100644
--- a/examples/inviscid-flow/CMakeLists.txt
+++ b/examples/inviscid-flow/CMakeLists.txt
@@ -1,2 +1,24 @@
-add_subdirectory( 1d )
-add_subdirectory( 2d )
+set( tnl_inviscid_flow_HEADERS
+     CompressibleConservativeVariables.h )
+
+set( tnl_inviscid_flow_SOURCES     
+     euler.cpp
+     euler.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler.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_inviscid_flow_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-2d )
+
diff --git a/examples/inviscid-flow/CompressibleConservativeVariables.h b/examples/inviscid-flow/CompressibleConservativeVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..04f1214999de5e6154131461098a061c2cfca311
--- /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::getMeshDimensions();
+      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..42ea19c145fd164d020af76b974c58020e8184e5
--- /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::getMeshDimensions();
+      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..9cc5ddc7f0ec7ec3aca8452eaecea7187d632963
--- /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::getMeshDimensions();
+      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::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 >();
+         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::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 >();
+         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::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+         //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  = neighbourEntities.template getEntityIndex<  1,  0,  0 >(); 
+         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0,  0 >(); 
+         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >(); 
+         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >(); 
+         const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >();
+         
+         const RealType& 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..df1570f19ca13f32bcb408c83a658a5e8f0cad81
--- /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::getMeshDimensions();
+      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::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 >();
+         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::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 >();
+         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::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 >();
+         
+         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..b3eb777b890cca2eb22b7a988edfa4d0dde5c956
--- /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::getMeshDimensions();
+      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..c4f004fa4eb447f06bc5e0b95e65be50f6347f8b
--- /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::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 >();
+         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::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 >();
+         
+         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::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 >();
+         
+         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..2b931be883e81dbb066c404d22d292482e85ff14
--- /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::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+         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::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 >();
+         
+         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::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 >();
+         
+         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..0ab7da1234570de3e5ab0edabafdca17ce8e719d
--- /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::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+         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::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+         static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+         //const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+         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::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 >();
+         
+         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..25108da0791e266f48f32e0ae0c7296d4e2ef18b
--- /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::getMeshDimensions();
+      
+      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..0de73687f12ef63d54026b9366687f794dc4d373
--- /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::getMeshDimensions();
+      typedef Containers::StaticVector< Dimensions, RealType > VertexType;
+      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 VertexType& v )
+      {
+         this->discontinuityPlacement = v;
+      }
+      
+      const VertexType& 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 VertexType& leftVelocity )
+      {
+         this->leftVelocity = leftVelocity;
+      }
+      
+      const VertexType& getLeftVelocity() const
+      {
+         return this->leftVelocity;
+      }
+      
+      void setRightVelocity( const RealType& rightVelocity )
+      {
+         this->rightVelocity = rightVelocity;
+      }
+      
+      const VertexType& 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 VertexType& center = VertexType( 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:
+      
+      VertexType discontinuityPlacement;
+      
+      RealType leftDensity, rightDensity;
+      VertexType 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 82%
rename from examples/inviscid-flow/1d/euler.h
rename to examples/inviscid-flow/euler.h
index 65bf55820659f8ce67d3a1cfd5622e1f558dab72..baa8941346311cd651c3f7443c11c56f2c690651 100644
--- a/examples/inviscid-flow/1d/euler.h
+++ b/examples/inviscid-flow/euler.h
@@ -6,20 +6,21 @@
 #include <TNL/Functions/Analytic/Constant.h>
 #include "eulerProblem.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;
@@ -29,19 +30,14 @@ 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.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.
@@ -115,5 +111,3 @@ int main( int argc, char* argv[] )
       return EXIT_FAILURE;
    return EXIT_SUCCESS;
 }
-
-
diff --git a/examples/inviscid-flow/1d/eulerBuildConfigTag.h b/examples/inviscid-flow/eulerBuildConfigTag.h
similarity index 96%
rename from examples/inviscid-flow/1d/eulerBuildConfigTag.h
rename to examples/inviscid-flow/eulerBuildConfigTag.h
index abede16343a81cde5e75386f8b2e15117fd6672d..2bb81e8cb3cd81772c4c5722ca9c5a518ffea25a 100644
--- a/examples/inviscid-flow/1d/eulerBuildConfigTag.h
+++ b/examples/inviscid-flow/eulerBuildConfigTag.h
@@ -21,7 +21,7 @@ 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 == 1 ) }; };
+template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = true }; };
 
 /****
  * Use of Grid is enabled for allowed dimensions and Real, Device and Index types.
diff --git a/examples/inviscid-flow/1d/eulerProblem.h b/examples/inviscid-flow/eulerProblem.h
similarity index 64%
rename from examples/inviscid-flow/1d/eulerProblem.h
rename to examples/inviscid-flow/eulerProblem.h
index f687ee5460accc7a593bb8f6e034872f8d8e6eda..79cff960a4e6801900cf43990f3cae0d23178ee2 100644
--- a/examples/inviscid-flow/1d/eulerProblem.h
+++ b/examples/inviscid-flow/eulerProblem.h
@@ -1,33 +1,40 @@
-#ifndef eulerPROBLEM_H_
-#define eulerPROBLEM_H_
+/***************************************************************************
+                          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;
+
 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::Momentum Momentum;
-      typedef typename DifferentialOperator::Energy Energy;
-      typedef typename DifferentialOperator::Velocity Velocity;
-      typedef typename DifferentialOperator::Pressure Pressure;
-      
+      static const int Dimensions = Mesh::getMeshDimensions();      
 
+      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();
 
@@ -51,9 +62,9 @@ class eulerProblem:
       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,
@@ -90,7 +101,7 @@ class eulerProblem:
                                  Matrix& matrix,
                                  DofVectorPointer& rightHandSide,
                                  MeshDependentDataPointer& meshDependentData );
-      
+
       bool postIterate( const RealType& time,
                         const RealType& tau,
                         const MeshPointer& mesh,
@@ -99,22 +110,21 @@ class eulerProblem:
 
    protected:
 
-      DifferentialOperatorPointer differentialOperatorPointer;
-      BoundaryConditionPointer boundaryConditionsPointer;
+      InviscidOperatorsPointer inviscidOperatorsPointer;
+         
+      BoundaryConditionPointer boundaryConditionPointer;
       RightHandSidePointer rightHandSidePointer;
       
-      MeshFunctionPointer uRho, uRhoVelocity, uEnergy;
-      MeshFunctionPointer fuRho, fuRhoVelocity, fuEnergy;
+      ConservativeVariablesPointer conservativeVariables,
+                                   conservativeVariablesRHS;
       
-      MeshFunctionPointer pressure, velocity, rho, rhoVel, energy;
+      VelocityFieldPointer velocity;
+      MeshFunctionPointer pressure;
       
-      RealType gamma;
-
-
+      RealType gamma;          
 };
 
-} // namepsace TNL
+} // namespace TNL
 
 #include "eulerProblem_impl.h"
 
-#endif /* eulerPROBLEM_H_ */
diff --git a/examples/inviscid-flow/2d/eulerProblem_impl.h b/examples/inviscid-flow/eulerProblem_impl.h
similarity index 51%
rename from examples/inviscid-flow/2d/eulerProblem_impl.h
rename to examples/inviscid-flow/eulerProblem_impl.h
index 27d4aa4ae67b7cacf7fdfb13214349a8a996a874..08b12e344e7551f2c0f3b8dead00f8dbe8c2c891 100644
--- a/examples/inviscid-flow/2d/eulerProblem_impl.h
+++ b/examples/inviscid-flow/eulerProblem_impl.h
@@ -1,3 +1,13 @@
+/***************************************************************************
+                          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>
@@ -5,24 +15,27 @@
 #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 "EulerPressureGetter.h"
-#include "EulerVelXGetter.h"
-#include "EulerVelYGetter.h"
-#include "EulerVelGetter.h"
+#include "LaxFridrichsMomentumZ.h"
 
 namespace TNL {
 
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 getTypeStatic()
 {
    return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
@@ -31,20 +44,20 @@ getTypeStatic()
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 String
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 getPrologHeader() const
 {
-   return String( "euler2D" );
+   return String( "Inviscid flow solver" );
 }
 
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) const
 {
    /****
@@ -56,115 +69,83 @@ writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) cons
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 setup( const MeshPointer& meshPointer,
        const Config::ParameterContainer& parameters,
        const String& prefix )
 {
-   if( ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ||
+   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 DifferentialOperator >
-typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+          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 4*mesh->template getEntitiesCount< typename MeshType::Cell >();
+   return this->conservativeVariables->getDofs( mesh );
 }
 
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 bindDofs( const MeshPointer& mesh,
           DofVectorPointer& dofVector )
 {
+   this->conservativeVariables->bind( mesh, dofVector );
 }
 
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 setInitialCondition( const Config::ParameterContainer& parameters,
                      const MeshPointer& mesh,
                      DofVectorPointer& dofs,
                      MeshDependentDataPointer& meshDependentData )
 {
-   typedef typename MeshType::Cell Cell;
-   double gamma = parameters.getParameter< double >( "gamma" );
-   double rhoL = parameters.getParameter< double >( "left-density" );
-   double velLX = parameters.getParameter< double >( "left-velocityX" );
-   double velLY = parameters.getParameter< double >( "left-velocityY" );
-   double preL = parameters.getParameter< double >( "left-pressure" );
-   double eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * ::pow(velLX,2) + ::pow(velLY,2);
-   double rhoR = parameters.getParameter< double >( "right-density" );
-   double velRX = parameters.getParameter< double >( "right-velocityX" );
-   double velRY = parameters.getParameter< double >( "right-velocityY" );
-   double preR = parameters.getParameter< double >( "right-pressure" );
-   double eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * ::pow(velRX,2) + ::pow(velRY,2);
-   double x0 = parameters.getParameter< double >( "riemann-border" );
-   int size = mesh->template getEntitiesCount< Cell >();
-   int size2 = size * size;
-   this->rho.bind( *dofs, 0, size2 );
-   this->rhoVelX.bind( *dofs, size2,size2);
-   this->rhoVelY.bind( *dofs, 2*size2,size2);
-   this->energy.bind( *dofs,3*size2,size2);
-   this->data.setSize( 4*size2);
-   this->pressure.bind(this->data,0,size2);
-   this->velocity.bind(this->data,size2,size2);
-   this->velocityX.bind(this->data,2*size2,size2);
-   this->velocityY.bind(this->data,3*size2,size2);
-   for(long int j = 0; j < size; j++)   
-      for(long int i = 0; i < size; i++)
-         if ((i < x0 * size)&&(j < x0 * size) )
-            {
-               this->rho[j*size+i] = rhoL;
-               this->rhoVelX[j*size+i] = rhoL * velLX;
-               this->rhoVelY[j*size+i] = rhoL * velLY;
-               this->energy[j*size+i] = eL;
-               this->velocity[j*size+i] = ::sqrt( ::pow(velLX,2) + ::pow(velLY,2) );
-               this->velocityX[j*size+i] = velLX;
-               this->velocityY[j*size+i] = velLY;
-               this->pressure[j*size+i] = preL;
-            }
-         else
-            {
-               this->rho[j*size+i] = rhoR;
-               this->rhoVelX[j*size+i] = rhoR * velRX;
-               this->rhoVelY[j*size+i] = rhoR * velRY;
-               this->energy[j*size+i] = eR;
-               this->velocity[j*size+i] = ::sqrt( ::pow(velRX,2) + :: pow(velRY,2) );
-               this->velocityX[j*size+i] = velRX;
-               this->velocityY[j*size+i] = velRY;
-               this->pressure[j*size+i] = preR;
-            };
-   this->gamma = gamma;
-   return true; 
+   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 DifferentialOperator >
+          typename InviscidOperators >
    template< typename Matrix >
 bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 setupLinearSystem( const MeshPointer& mesh,
                    Matrix& matrix )
 {
@@ -173,7 +154,7 @@ setupLinearSystem( const MeshPointer& mesh,
    CompressedRowsLengthsVectorType rowLengths;
    if( ! rowLengths.setSize( dofs ) )
       return false;
-   MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
+   MatrixSetter< MeshType, InviscidOperators, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
    matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh,
                                                                           differentialOperator,
                                                                           boundaryCondition,
@@ -187,9 +168,9 @@ setupLinearSystem( const MeshPointer& mesh,
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 makeSnapshot( const RealType& time,
               const IndexType& step,
               const MeshPointer& mesh,
@@ -197,44 +178,40 @@ makeSnapshot( const RealType& time,
               MeshDependentDataPointer& meshDependentData )
 {
   std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl;
-   this->bindDofs( mesh, dofs );
+  
+  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( "rho-" );
-   if( ! this->rho.save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "rhoVelX-" );
-   if( ! this->rhoVelX.save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "rhoVelY-" );
-   if( ! this->rhoVelY.save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "energy-" );
-   if( ! this->energy.save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocityX-" );
-   if( ! this->velocityX.save( fileName.getFileName() ) )
-      return false;
-   fileName.setFileNameBase( "velocityY-" );
-   if( ! this->velocityY.save( fileName.getFileName() ) )
+   fileName.setFileNameBase( "density-" );
+   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
       return false;
+   
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity.save( fileName.getFileName() ) )
+   if( ! this->velocity->save( fileName.getFileName() ) )
       return false;
-   fileName.setFileNameBase( "pressue-" );
-   if( ! this->pressure.save( fileName.getFileName() ) )
+
+   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 DifferentialOperator >
+          typename InviscidOperators >
 void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 getExplicitRHS( const RealType& time,
                 const RealType& tau,
                 const MeshPointer& mesh,
@@ -243,92 +220,100 @@ getExplicitRHS( const RealType& time,
                 MeshDependentDataPointer& meshDependentData )
 {
     typedef typename MeshType::Cell Cell;
-    int count = mesh->template getEntitiesCount< Cell >()/4;
-	//bind _u
-    this->_uRho.bind( *_u,0,count);
-    this->_uRhoVelocityX.bind( *_u,count,count);
-    this->_uRhoVelocityY.bind( *_u,2 * count,count);
-    this->_uEnergy.bind( *_u,3 * count,count);
-		
-	//bind _fu
-    this->_fuRho.bind( *_u,0,count);
-    this->_fuRhoVelocityX.bind( *_u,count,count);
-    this->_fuRhoVelocityY.bind( *_u,2 * count,count);
-    this->_fuEnergy.bind( *_u,3 * count,count);
-   //bind MeshFunctionType
-   MeshFunctionPointer velocity( mesh, this->velocity );
-   MeshFunctionPointer velocityX( mesh, this->velocityX );
-   MeshFunctionPointer velocityY( mesh, this->velocityY );
-   MeshFunctionPointer pressure( mesh, this->pressure );
-   MeshFunctionPointer uRho( mesh, _uRho ); 
-   MeshFunctionPointer fuRho( mesh, _fuRho );
-   MeshFunctionPointer uRhoVelocityX( mesh, _uRhoVelocityX ); 
-   MeshFunctionPointer fuRhoVelocityX( mesh, _fuRhoVelocityX );
-   MeshFunctionPointer uRhoVelocityY( mesh, _uRhoVelocityY ); 
-   MeshFunctionPointer fuRhoVelocityY( mesh, _fuRhoVelocityY );
-   MeshFunctionPointer uEnergy( mesh, _uEnergy ); 
-   MeshFunctionPointer fuEnergy( mesh, _fuEnergy );
-   //generate Operators
-   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; 
+    
+    /****
+     * 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.template update< typename Mesh::Cell >( time,
                                                            mesh,
-                                                           lF2DContinuity,
+                                                           this->inviscidOperatorsPointer->getContinuityOperator(),
                                                            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; 
+                                                           this->conservativeVariables->getDensity(),
+                                                           this->conservativeVariablesRHS->getDensity() );
+
+   /****
+    * Momentum equations
+    */
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumXOperatorType, 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->inviscidOperatorsPointer->getMomentumXOperator(),
                                                            this->boundaryConditionPointer,
                                                            this->rightHandSidePointer,
-                                                           uRhoVelocityY,
-                                                           fuRhoVelocityY );
+                                                           ( *this->conservativeVariables->getMomentum() )[ 0 ], // uRhoVelocityX,
+                                                           ( *this->conservativeVariablesRHS->getMomentum() )[ 0 ] ); //, fuRhoVelocityX );
+
+   if( Dimensions > 1 )
+   {
+      Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumYOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY;
+      explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time,
+                                                              mesh,
+                                                              this->inviscidOperatorsPointer->getMomentumYOperator(),
+                                                              this->boundaryConditionPointer,
+                                                              this->rightHandSidePointer,
+                                                              ( *this->conservativeVariables->getMomentum() )[ 1 ], // uRhoVelocityX,
+                                                              ( *this->conservativeVariablesRHS->getMomentum() )[ 1 ] ); //, fuRhoVelocityX );
+   }
+   
+   if( Dimensions > 2 )
+   {
+      Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumZOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumZ;
+      explicitUpdaterMomentumZ.template update< typename Mesh::Cell >( time,
+                                                              mesh,
+                                                              this->inviscidOperatorsPointer->getMomentumZOperator(),
+                                                              this->boundaryConditionPointer,
+                                                              this->rightHandSidePointer,
+                                                              ( *this->conservativeVariables->getMomentum() )[ 2 ], // uRhoVelocityX,
+                                                              ( *this->conservativeVariablesRHS->getMomentum() )[ 2 ] ); //, fuRhoVelocityX );
+   }
+   
   
-   //energy
-   lF2DEnergy->setTau(tau);
-   lF2DEnergy->setVelocityX( *velocityX ); 
-   lF2DEnergy->setVelocityY( *velocityY ); 
-   lF2DEnergy->setPressure( *pressure );
-   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
+   /****
+    * Energy equation
+    */
+   Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, EnergyOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
    explicitUpdaterEnergy.template update< typename Mesh::Cell >( time,
                                                            mesh,
-                                                           lF2DEnergy,
+                                                           this->inviscidOperatorsPointer->getEnergyOperator(),
                                                            this->boundaryConditionPointer,
                                                            this->rightHandSidePointer,
-                                                           uEnergy,
-                                                           fuEnergy );
+                                                           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();*/
 
 /*
    BoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; 
@@ -341,10 +326,10 @@ getExplicitRHS( const RealType& time,
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
    template< typename Matrix >
 void
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::
 assemblyLinearSystem( const RealType& time,
                       const RealType& tau,
                       const MeshPointer& mesh,
@@ -355,7 +340,7 @@ assemblyLinearSystem( const RealType& time,
 {
 /*   LinearSystemAssembler< Mesh,
                              MeshFunctionType,
-                             DifferentialOperator,
+                             InviscidOperators,
                              BoundaryCondition,
                              RightHandSide,
                              BackwardTimeDiscretisation,
@@ -377,15 +362,16 @@ assemblyLinearSystem( const RealType& time,
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
-          typename DifferentialOperator >
+          typename InviscidOperators >
 bool
-eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+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
@@ -433,7 +419,8 @@ postIterate( const RealType& time,
    euler2DPressure.setRho(uRho);
 //   OperatorFunction< euler2DPressure, MeshFunction, void, time > OFPressure;
 //   pressure = OFPressure;
-
+    */
+   return true;
 }
 
 } // namespace TNL
diff --git a/examples/inviscid-flow/1d/eulerRhs.h b/examples/inviscid-flow/eulerRhs.h
similarity index 100%
rename from examples/inviscid-flow/1d/eulerRhs.h
rename to examples/inviscid-flow/eulerRhs.h
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/narrow-band/CMakeLists.txt b/examples/narrow-band/CMakeLists.txt
new file mode 100755
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..47d8648bbf7646cd9580134f55be6002359cf21e
--- /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,tnlHost, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		checkCudaDevice;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+//   else if(dim == 3)
+//   {
+//		tnlNarrowBand<tnlGrid<3,double,tnlHost, int>, double, int> solver;
+//		if(!solver.init(parameters))
+//	   {
+//			cerr << "Solver failed to initialize." << endl;
+//			return EXIT_FAILURE;
+//	   }
+//		checkCudaDevice;
+//	   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..e2817424a1feb0f24bcbf8a759d37e8c9697977d
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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..e532bca7774c9c42648bf43f648a07ebbf20eb78
--- /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();
+	checkCudaDevice;
+#endif
+
+	int n = Mesh.getDimensions().x();
+
+	dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocks2(statusGridSize ,statusGridSize);
+	initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+	initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+
+	/*dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);*/
+	initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+
+	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();
+	checkCudaDevice;
+	cout << "Hi2!" << endl;
+	while(time < finalTime)
+	{
+		if(tau+time > finalTime)
+			tau=finalTime-time;
+
+		runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+
+		time += tau;
+
+
+		cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		if(reinit != 0 /*&& time != finalTime */)
+		{
+			cout << time << endl;
+
+			initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+		}
+	}
+
+	//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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+		Entity.setCoordinates(CoordinatesType(i,j));
+		Entity.refresh();
+		tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real a,b, tmp;
+
+		if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9))*/ )
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17))*/ )
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 /*|| (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3))*/ )
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5)) */)
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighbourEntities.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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh);
+			Entity.setCoordinates(Containers::StaticVector<2,double>(i,j));
+			Entity.refresh();
+			tnlNeighbourGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()];
+				xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+			else if( i == solver->Mesh.getDimensions().x() - 1 || (threadIdx.x == blockDim.x - 1 && !(status & 17)) )
+			{
+				xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()] - value;
+			}
+			else
+			{
+				xb =  value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+
+			if( j == 0 || (threadIdx.y == 0 && !(status & 3)) )
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()] ;
+				yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			else if( j == solver->Mesh.getDimensions().y() - 1  || (threadIdx.y == blockDim.y - 1 && !(status & 5)) )
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+				yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()] - value;
+			}
+			else
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()];
+				yf = solver-> cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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..2d1296058391a0685d9385047469acb41a40b765
--- /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();
+	checkCudaDevice;
+#endif
+
+	int n = Mesh.getDimensions().x();
+
+	dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE);
+	dim3 numBlocks2(statusGridSize ,statusGridSize);
+	initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+	initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+
+	/*dim3 threadsPerBlock(16, 16);
+	dim3 numBlocks(n/16 + 1 ,n/16 +1);*/
+	initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+
+	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();
+	checkCudaDevice;
+	cout << "Hi2!" << endl;
+	while(time < finalTime)
+	{
+		if(tau+time > finalTime)
+			tau=finalTime-time;
+
+		runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+
+		time += tau;
+
+
+		cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		if(reinit != 0 /*&& time != finalTime */)
+		{
+			cout << time << endl;
+
+			initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+		}
+	}
+
+	//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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+		Entity.setCoordinates(CoordinatesType(i,j));
+		Entity.refresh();
+		tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real a,b, tmp;
+
+		if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9)) */)
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17)) */)
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0/* || (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3)) */)
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5))*/ )
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighbourEntities.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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh);
+			Entity.setCoordinates(Containers::StaticVector<2,double>(i,j));
+			Entity.refresh();
+			tnlNeighbourGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()];
+				xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+			else if( i == solver->Mesh.getDimensions().x() - 1 /*|| (threadIdx.x == blockDim.x - 1 && !(status & 17)) */)
+			{
+				xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()] - value;
+			}
+			else
+			{
+				xb =  value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+				xf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] - value;
+			}
+
+			if( j == 0/* || (threadIdx.y == 0 && !(status & 3))*/ )
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()] ;
+				yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()] - value;
+			}
+			else if( j == solver->Mesh.getDimensions().y() - 1  /*|| (threadIdx.y == blockDim.y - 1 && !(status & 5)) */)
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+				yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()] - value;
+			}
+			else
+			{
+				yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()];
+				yf = solver-> cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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..8248baa0949862de6ebcee797e6916c9634de72e
--- /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()
+{
+
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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();
+			neighbourEntities.refresh(Mesh,Entity.getIndex());
+
+				if(dofVector[this->Entity.getIndex()] > 0)
+				{
+					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1111(i,j);
+							else
+								setupSquare1110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1101(i,j);
+							else
+								setupSquare1100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1011(i,j);
+							else
+								setupSquare1010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1001(i,j);
+							else
+								setupSquare1000(i,j);
+						}
+					}
+				}
+				else
+				{
+					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0111(i,j);
+							else
+								setupSquare0110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0101(i,j);
+							else
+								setupSquare0100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0011(i,j);
+							else
+								setupSquare0010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.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();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+				 dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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..ac8a023d7d93060f63858892c0541f5eda0ee706
--- /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();
+	checkCudaDevice;
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+
+	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, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity);
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()],
+				 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()],
+				 cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0 >()] );
+	}
+
+	if( k == 0 )
+		c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()];
+	else
+	{
+		c = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()],
+				 cudaDofVector2[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, 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..eb446d9d2831967e9016b3eaaf326baf6751ab7c
--- /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();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity);
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0>()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0>()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0>()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0>()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0>()];
+	else
+	{
+		b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0>()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0>()] );
+	}
+
+	if( k == 0 )
+		c = dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  1>()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1>()];
+	else
+	{
+		c = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1>()],
+				 dofVector2[neighbourEntities.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..8da92f5fc570275c85ebba69113f0e59a4be7988
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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, tnlHost, int >, double, int >* solver, int sweep, int i);
+//__global__ void runCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+
+__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+__global__ void initSetupGrid1_2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, double tau);
+//__global__ void initCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, 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/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/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/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..08f0a6fbeb66a74177d52584344af718a911a074
--- /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::getMeshDimensions();
+      
+      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::getMeshDimensions(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblemEoc< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         if( boundaryConditionsType == "neumann" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), 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/examples/transport-equation/tnl-transport-equation.cpp b/examples/transport-equation/tnl-transport-equation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f8cc396d31d0592dc8626c370015886f1d3b2dc4
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation.cpp
@@ -0,0 +1,11 @@
+/***************************************************************************
+                          tnl-transport-equation.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.h"
diff --git a/examples/transport-equation/tnl-transport-equation.cu b/examples/transport-equation/tnl-transport-equation.cu
new file mode 100644
index 0000000000000000000000000000000000000000..068984a891fdc9df2c58ad24ae7a5c9b87ef015d
--- /dev/null
+++ b/examples/transport-equation/tnl-transport-equation.cu
@@ -0,0 +1,11 @@
+/***************************************************************************
+                          tnl-transport-equation.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.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..ad9cc970a3000384cd4a49e5d369f1326c59453d
--- /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::getMeshDimensions();
+      
+      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::getMeshDimensions(), Real, Index > BoundaryConditions;
+            typedef transportEquationProblem< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem;
+            return callSolverStarter< Problem >( parameters );
+         }
+         if( boundaryConditionsType == "neumann" )
+         {
+            typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), 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..df87a06b2b818ec466449ccab911cbcccd8bfb4a
--- /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 = ConfigTagDimensions< 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 76%
rename from examples/advection/advectionProblem.h
rename to examples/transport-equation/transportEquationProblem.h
index a44048c08c7899a47a8ee27a6f91a5d758eff1f4..8e7e164ab2688e600ad8a1578985a1f90d834138 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;
@@ -93,13 +104,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/transport-equation/transportEquationProblemEoc.h b/examples/transport-equation/transportEquationProblemEoc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f2c8ea3ae6749b2f5c3b9896c2f4a8b5ad35500
--- /dev/null
+++ b/examples/transport-equation/transportEquationProblemEoc.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+                          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 transportEquationProblemEoc:
+public transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >
+{
+   public:
+
+      typedef typename DifferentialOperator::RealType RealType;
+      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 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; 
+      
+      //using BaseType::getExplicitRHS;
+      
+      static String getTypeStatic();
+
+      String getPrologHeader() const;
+
+      bool setup( const MeshPointer& meshPointer,
+                  const Config::ParameterContainer& parameters,
+                  const String& prefix = "" );
+
+      bool setInitialCondition( const Config::ParameterContainer& parameters,
+                                const MeshPointer& mesh,
+                                DofVectorPointer& dofs,
+                                MeshDependentDataPointer& meshDependentData );
+
+      /*template< typename Matrix >
+      bool setupLinearSystem( const MeshPointer& mesh,
+                              Matrix& matrix );
+
+      bool makeSnapshot( const RealType& time,
+                         const IndexType& step,
+                         const MeshPointer& mesh,
+                         DofVectorPointer& dofs,
+                         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,
+                           MeshDependentDataPointer& meshDependentData );*/
+
+
+   protected:
+};
+
+} // namespace TNL
+
+#include "transportEquationProblemEoc_impl.h"
+
diff --git a/examples/transport-equation/transportEquationProblemEoc_impl.h b/examples/transport-equation/transportEquationProblemEoc_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..c238bc311b5ea0e25745eef64e58ad9d1e3caa57
--- /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 Dimensions = Mesh::getMeshDimensions();
+   typedef typename MeshPointer::ObjectType MeshType;
+   typedef Functions::MeshFunction< MeshType > MeshFunction;
+   SharedPointer< MeshFunction > u( meshPointer );
+   if( initialCondition == "heaviside-vector-norm" )
+   {
+      typedef Functions::Analytic::VectorNorm< Dimensions, RealType > VectorNormType;
+      typedef Operators::Analytic::Heaviside< Dimensions, RealType > HeavisideType;
+      typedef Functions::OperatorFunction< HeavisideType, VectorNormType > InitialConditionType;
+      String velocityFieldType = parameters.getParameter< String >( "velocity-field" );
+      if( velocityFieldType == "constant" )
+      {      
+         typedef Operators::Analytic::Shift< Dimensions, 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< Dimensions, RealType > velocity;
+         for( int i = 0; i < Dimensions; 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..7e2023ad2fb39a2381b71ecca0705fa0d09ff56f
--- /dev/null
+++ b/examples/transport-equation/transportEquationProblem_impl.h
@@ -0,0 +1,233 @@
+/***************************************************************************
+                          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 >::
+getExplicitRHS( 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.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
+transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshPointer& mesh,
+                      DofVectorPointer& _u,
+                      Matrix& matrix,
+                      DofVectorPointer& b,
+                      MeshDependentDataPointer& meshDependentData )
+{
+}
+
+} // namespace TNL
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/ParameterContainer.h b/src/TNL/Config/ParameterContainer.h
index 5f6df343000fe3a28eb1afe5edc1f54156ba451d..5ac93da80dfda6eac8333d6f08540ea6683f4d71 100644
--- a/src/TNL/Config/ParameterContainer.h
+++ b/src/TNL/Config/ParameterContainer.h
@@ -14,6 +14,7 @@
 #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;
    }
 
diff --git a/src/TNL/Containers/Algorithms/CudaReductionKernel.h b/src/TNL/Containers/Algorithms/CudaReductionKernel.h
index e2ab7e2cebc348e0797cf11a88775a3e7b5c388d..98a8841a36917cbb420dd54ef25c619a699853fb 100644
--- a/src/TNL/Containers/Algorithms/CudaReductionKernel.h
+++ b/src/TNL/Containers/Algorithms/CudaReductionKernel.h
@@ -123,7 +123,7 @@ CudaReductionKernel( Operation operation,
 
    /***
     * This runs in one warp so it is synchronized implicitly.
-    */
+    */   
    if( tid < 32 )
    {
       volatile ResultType* vsdata = sdata;
@@ -132,6 +132,8 @@ CudaReductionKernel( Operation operation,
          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 ] );
diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h
index 65c2bc58f487460137b3bc4996264552345ab062..e9d34f860fa6c0dcff23e9847c311a3fe4d85e45 100644
--- a/src/TNL/Containers/Array_impl.h
+++ b/src/TNL/Containers/Array_impl.h
@@ -22,6 +22,8 @@
 namespace TNL {
 namespace Containers {   
 
+using namespace std;
+
 template< typename Element,
           typename Device,
           typename Index >
@@ -177,9 +179,9 @@ setSize( const Index size )
    this->size = size;
    if( size > 0 && ! 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;
+      cerr << "I am not able to allocate new array with size "
+           << ( double ) this->size * sizeof( ElementType ) / 1.0e9 << " GB." << endl;
+      this -> size = 0;
       return false;
    }
    return true;
@@ -299,7 +301,7 @@ Index
 Array< Element, Device, Index >::
 getSize() const
 {
-   return this->size;
+   return this -> size;
 }
 
 template< typename Element,
@@ -411,7 +413,7 @@ bool
 Array< Element, Device, Index >::
 operator == ( const ArrayT& array ) const
 {
-   if( array. getSize() != this->getSize() )
+   if( array. getSize() != this -> getSize() )
       return false;
    if( this->getSize() == 0 )
       return true;
@@ -449,7 +451,7 @@ template< typename Element,
 __cuda_callable__
 const Element* Array< Element, Device, Index > :: getData() const
 {
-   return this->data;
+   return this -> data;
 }
 
 template< typename Element,
@@ -458,7 +460,7 @@ template< typename Element,
 __cuda_callable__
 Element* Array< Element, Device, Index > :: getData()
 {
-   return this->data;
+   return this -> data;
 }
 
 template< typename Element,
@@ -495,8 +497,8 @@ bool Array< Element, Device, Index > :: save( File& file ) const
 #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;
+      cerr << "I was not able to save " << this->getType()
+           << " with size " << this -> getSize() << endl;
       return false;
    }
    return true;
@@ -521,7 +523,7 @@ load( File& file )
 #endif
    if( _size < 0 )
    {
-      std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
+      cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << endl;
       return false;
    }
    setSize( _size );
@@ -529,8 +531,8 @@ 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;
+         cerr << "I was not able to load " << this->getType()
+                    << " with size " << this -> getSize() << endl;
          return false;
       }
    }
@@ -556,7 +558,7 @@ boundLoad( File& file )
 #endif
    if( _size < 0 )
    {
-      std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
+      cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << endl;
       return false;
    }
    if( this->getSize() != 0 )
@@ -573,8 +575,8 @@ 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;
+         cerr << "I was not able to load " << this->getType()
+                    << " with size " << this -> getSize() << endl;
          return false;
       }
    }
@@ -591,14 +593,14 @@ 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;
+      cerr << "I am not bale to open the file " << fileName << " for reading." << 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;
+      cerr << "An error occurred when I was closing the file " << fileName << "." << endl;
       return false;
    }
    return true;
diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h
index 2b0e7c7fdeb013e47d578a4ff33053a05aecde2e..a75f34d3b88f0390caec5ea0e10bd60c810bb8f0 100644
--- a/src/TNL/Containers/StaticVector.h
+++ b/src/TNL/Containers/StaticVector.h
@@ -23,6 +23,8 @@ class StaticVector : public Containers::StaticArray< Size, Real >
    typedef StaticVector< Size, Real > ThisType;
    enum { size = Size };
 
+   using Containers::StaticArray< Size, Real >::operator=;
+   
    __cuda_callable__
    StaticVector();
 
@@ -36,6 +38,9 @@ class StaticVector : public Containers::StaticArray< Size, Real >
    //! Copy constructor
    __cuda_callable__
    StaticVector( const StaticVector< Size, Real >& v );
+   
+   bool setup( const Config::ParameterContainer& parameters,
+               const String& prefix = "" );      
 
    static String getType();
 
@@ -85,6 +90,9 @@ class StaticVector : public Containers::StaticArray< Size, Real >
  
    __cuda_callable__
    ThisType abs() const;
+   
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;
 };
 
 template< typename Real >
@@ -94,7 +102,7 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
    typedef Real RealType;
    typedef StaticVector< 1, Real > ThisType;
    enum { size = 1 };
-
+   
    __cuda_callable__
    StaticVector();
 
@@ -105,6 +113,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,6 +165,9 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real >
  
    __cuda_callable__
    ThisType abs() const;
+   
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
 };
 
 template< typename Real >
@@ -163,7 +177,7 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
    typedef Real RealType;
    typedef StaticVector< 2, Real > ThisType;
    enum { size = 2 };
-
+   
    __cuda_callable__
    StaticVector();
 
@@ -180,6 +194,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,6 +246,9 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real >
  
    __cuda_callable__
    ThisType abs() const;
+   
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
 };
 
 template< typename Real >
@@ -238,7 +258,7 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
    typedef Real RealType;
    typedef StaticVector< 3, Real > ThisType;
    enum { size = 3 };
-
+   
    __cuda_callable__
    StaticVector();
 
@@ -255,6 +275,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,6 +327,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
  
    __cuda_callable__
    ThisType abs() const;
+   
+   __cuda_callable__
+   Real lpNorm( const Real& p ) const;   
 };
 
 template< int Size, typename Real, typename Scalar >
diff --git a/src/TNL/Containers/StaticVector1D_impl.h b/src/TNL/Containers/StaticVector1D_impl.h
index a8e4151a352a71b455f7404977d3e347874a46d2..ab2391eddacb43a5667d7c82d9c120a940bb1e6e 100644
--- a/src/TNL/Containers/StaticVector1D_impl.h
+++ b/src/TNL/Containers/StaticVector1D_impl.h
@@ -33,6 +33,15 @@ StaticVector< 1, Real >::StaticVector( const StaticVector< 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 +157,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..d5f63f283129ae11e50fcdd4352cff91eda26ea3 100644
--- a/src/TNL/Containers/StaticVector2D_impl.h
+++ b/src/TNL/Containers/StaticVector2D_impl.h
@@ -49,6 +49,16 @@ StaticVector< 2, Real >::StaticVector( const StaticVector< 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()
 {
@@ -177,6 +187,19 @@ StaticVector< 2, Real >::abs() const
                                       ::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 std::sqrt( this->data[ 0 ] * this->data[ 0 ] + 
+                        this->data[ 1 ] * this->data[ 1 ] );
+   return std::pow( std::pow( TNL::abs( this->data[ 0 ] ), p ) +
+                    std::pow( TNL::abs( this->data[ 1 ] ), p ), 1.0 / p ); 
+}
 
 #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION
 
@@ -195,3 +218,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..68f5802e2772884305e3a6e6e50db913e1b8319d 100644
--- a/src/TNL/Containers/StaticVector3D_impl.h
+++ b/src/TNL/Containers/StaticVector3D_impl.h
@@ -47,6 +47,17 @@ StaticVector< 3, Real >::StaticVector( const StaticVector< 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 >
 String StaticVector< 3, Real >::getType()
 {
@@ -187,6 +198,25 @@ StaticVector< 3, Real >::abs() const
                                       ::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 std::sqrt( this->data[ 0 ] * this->data[ 0 ] + 
+                        this->data[ 1 ] * this->data[ 1 ] +
+                        this->data[ 2 ] * this->data[ 2 ] );
+   return std::pow( std::pow( TNL::abs( this->data[ 0 ] ), p ) +
+                    std::pow( TNL::abs( this->data[ 1 ] ), p ) +
+                    std::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 32b8f4b95ece7bdc9c6e0a435c072e17e58e8979..8c8d37b9c0c0e5b3f58a5f182f75f2837eddf156 100644
--- a/src/TNL/Containers/StaticVector_impl.h
+++ b/src/TNL/Containers/StaticVector_impl.h
@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include <TNL/Config/ParameterContainer.h>
+
 namespace TNL {
 namespace Containers {   
 
@@ -40,6 +42,17 @@ StaticVector< Size, Real >::StaticVector( const StaticVector< 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,6 +193,30 @@ StaticVector< Size, Real >::abs() const
    return v;
 }
 
+template< int Size, typename Real >
+__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 std::sqrt( aux );
+   }
+   Real aux = std::pow( TNL::abs( this->data[ 0 ] ), p );
+   for( int i = 1; i < Size; i++ )
+      aux += std::pow( TNL::abs( this->data[ i ] ), p );
+   return std::pow( aux, 1.0 / p );
+}
 
 template< int Size, typename Real, typename Scalar >
 __cuda_callable__
diff --git a/src/TNL/Debugging/StackBacktrace.h b/src/TNL/Debugging/StackBacktrace.h
index 17e576fd7219e6da8b4b7e3bfc5beab4510d42cc..ee419922637899c7187e25d187abc6a427ebff68 100644
--- a/src/TNL/Debugging/StackBacktrace.h
+++ b/src/TNL/Debugging/StackBacktrace.h
@@ -18,6 +18,7 @@
 namespace TNL {
 namespace Debugging {
 
+#ifndef NDEBUG
 /*
  * Print a demangled stack backtrace of the caller function to FILE* out.
  *
@@ -99,6 +100,13 @@ printStackBacktrace( FILE *out = stderr, unsigned int max_frames = 63 )
    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/Experimental/CMakeLists.txt b/src/TNL/Experimental/CMakeLists.txt
index acb1a43c37120ab468bea9a3e1126c319d2dca92..47fc9efa44f92699b64e247af1778ad83e6cebfa 100755
--- 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 100755
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 100755
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..202550179b61cbf4a47bca43f96f751d0e2510eb
--- /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}/implementation/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..a90c7258438a52c0afebf2d0e9838e1491f16a13
--- /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 tnlVector< 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 NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1 >() ];
+         const RealType& u_w = u[ neighbourEntities.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 tnlVector< 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 NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();   
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex<  1,  0 >() ];
+         const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1,  0 >() ];
+         const RealType& u_n = u[ neighbourEntities.template getEntityIndex<  0,  1 >() ];
+         const RealType& u_s = u[ neighbourEntities.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 tnlVector< 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 NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ];
+         const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ];
+         const RealType& u_n = u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ];
+         const RealType& u_s = u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ];
+         const RealType& u_t = u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ];
+         const RealType& u_b = u[ neighbourEntities.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 100755
index 0000000000000000000000000000000000000000..8b74f755ed0a74e7001f1c155c60f61c650679d2
--- /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}/implementation/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..d4941ba38a992fd76047a7ead2f538b79af2f079
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+                          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 <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.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 tnlVector< 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 tnlVector< 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 tnlVector< 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..e2f1859231a8096ae38e0dcaff664f490efa5cfc
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h
@@ -0,0 +1,269 @@
+/***************************************************************************
+                          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 <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.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 tnlVector< 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 tnlVector< 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) 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 tnlVector< 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities  ) 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities ) 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..29738ab330e3b951d6b8a9bd6be89b5606c0f5b0
--- /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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities ) 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[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighbourEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighbourEntities.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[neighbourEntities.template getEntityIndex< -1,  0 >()] - u[cellIndex])*ihx);
+//		   else
+//			   xf = negativePart((u[neighbourEntities.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[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  -1 >()] - u[cellIndex])*ihy);
+//		   else
+//			   yf = negativePart((u[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()])*ihy);
+//		   else
+//			   yb = positivePart((u[cellIndex] - u[neighbourEntities.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[neighbourEntities.template getEntityIndex< -1,  0 >()] - u[cellIndex])*ihx);
+//		   else
+//			   xf = positivePart((u[neighbourEntities.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[neighbourEntities.template getEntityIndex< 1,  0 >()])*ihx);
+//		   else
+//			   xb = negativePart((u[cellIndex] - u[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  -1 >()] - u[cellIndex])*ihy);
+//		   else
+//			   yf = positivePart((u[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()])*ihy);
+//		   else
+//			   yb = negativePart((u[cellIndex] - u[neighbourEntities.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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) 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[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighbourEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighbourEntities.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..3aa8aeed5357e7a4f0b0f176e9002c89a4295a84
--- /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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities  ) 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[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+	   else
+		   xf += u[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+	   else
+		   xb -= u[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+	   else
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+	   else
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+
+
+	   if(coordinates.z() == mesh.getDimensions().z() - 1)
+		   zf += u[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()];
+	   else
+		   zf += u[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+
+	   if(coordinates.z() == 0)
+		   zb -= u[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+	   else
+		   zb -= u[neighbourEntities.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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 ) 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[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+		   else
+			   xf += u[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+
+		   if(coordinates.x() == 0)
+			   xb -= u[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+		   else
+			   xb -= u[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+
+		   if(coordinates.y() == mesh.getDimensions().y() - 1)
+			   yf += u[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+		   else
+			   yf += u[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+
+		   if(coordinates.y() == 0)
+			   yb -= u[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+		   else
+			   yb -= u[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+
+
+		   if(coordinates.z() == mesh.getDimensions().z() - 1)
+			   zf += u[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()];
+		   else
+			   zf += u[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+
+		   if(coordinates.z() == 0)
+			   zb -= u[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+		   else
+			   zb -= u[neighbourEntities.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..db7a087224b933150fcda1ed47119d2e23448000
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h
@@ -0,0 +1,271 @@
+/***************************************************************************
+                          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 <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.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 tnlVector< 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 tnlVector< 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities,
+                   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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities,
+  	  	  	       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 tnlVector< 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities  ) 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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities) 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..c5f7d613497e7f61b449a2e16190c18988a12c3f
--- /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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities,
+          	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 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[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighbourEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighbourEntities.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 tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities,
+          	  	  	  	  	  	  	  	  	  	                     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[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	   else
+		   xf += u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+
+	   if(coordinates.x() == 0)
+		   xb -= u[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	   else
+		   xb -= u[neighbourEntities.template getEntityIndex< -1,  0 >()];
+
+	   if(coordinates.y() == mesh.getDimensions().y() - 1)
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	   else
+		   yf += u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+
+	   if(coordinates.y() == 0)
+		   yb -= u[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	   else
+		   yb -= u[neighbourEntities.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 100755
index 0000000000000000000000000000000000000000..74f7510d72329f60305bb366604e72b7201a3ea0
--- /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}/implementation/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..3beb7e997e0f7aa6759df7c571b3a398445630b9
--- /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::getMeshDimensions(),
+                                 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 getMeshDimensions() { 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..e8f793260999eba3f7e2082a5237ee3daba6e86a
--- /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 tnlVector< 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 NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1 >() ];
+         const RealType& u_w = u[ neighbourEntities.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 tnlVector< 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 NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();   
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex<  1,  0 >() ];
+         const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1,  0 >() ];
+         const RealType& u_n = u[ neighbourEntities.template getEntityIndex<  0,  1 >() ];
+         const RealType& u_s = u[ neighbourEntities.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 tnlVector< 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 NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const RealType& u_c = u[ entity.getIndex() ];
+         const RealType& u_e = u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ];
+         const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ];
+         const RealType& u_n = u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ];
+         const RealType& u_s = u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ];
+         const RealType& u_t = u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ];
+         const RealType& u_b = u[ neighbourEntities.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 100755
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 100755
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..d17b47ac5125bebf9ac9619a9496b5dc4b46b394
--- /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,tnlHost, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		checkCudaDevice;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+//   else if(dim == 3)
+//   {
+//		tnlFastSweepingMap<tnlGrid<3,double,tnlHost, int>, double, int> solver;
+//		if(!solver.init(parameters))
+//	   {
+//			cerr << "Solver failed to initialize." << endl;
+//			return EXIT_FAILURE;
+//	   }
+//		checkCudaDevice;
+//	   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..f6f2150a4df3ae6f0fe85efeeb6ea9abac0007d3
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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..5e9d11b5264e301d8eb9a30b625861bf6a79ad2b
--- /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();
+	checkCudaDevice;
+
+	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();
+		checkCudaDevice;
+
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0, this->changed);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+
+		cudaMemcpy(&run, this->changed,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		cntr++;
+		cout << "Finished set of sweeps #" << cntr << "           " << run << endl;
+	}
+
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+	//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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+
+	if(map_cuda[Entity.getIndex()] != 0.0)
+	{
+		tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+		Real value = cudaDofVector2[Entity.getIndex()];
+		Real im = abs(1.0/map_cuda[Entity.getIndex()]);
+		Real a,b, tmp;
+
+		if( i == 0 )
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 )
+			a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+					 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 )
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 )
+			b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+					 cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1111(i,j);
+//					else
+//						setupSquare1110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1101(i,j);
+//					else
+//						setupSquare1100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1011(i,j);
+//					else
+//						setupSquare1010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare1001(i,j);
+//					else
+//						setupSquare1000(i,j);
+//				}
+//			}
+//		}
+//		else
+//		{
+//			if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0111(i,j);
+//					else
+//						setupSquare0110(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0101(i,j);
+//					else
+//						setupSquare0100(i,j);
+//				}
+//			}
+//			else
+//			{
+//				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//				{
+//					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//						setupSquare0011(i,j);
+//					else
+//						setupSquare0010(i,j);
+//				}
+//				else
+//				{
+//					if(cudaDofVector[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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..adff615fd43cd012ba5e45095140d7c2e0e5fbf0
--- /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()
+{
+
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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();
+//			neighbourEntities.refresh(Mesh,Entity.getIndex());
+//
+//				if(dofVector[this->Entity.getIndex()] > 0)
+//				{
+//					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//					{
+//						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1111(i,j);
+//							else
+//								setupSquare1110(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1101(i,j);
+//							else
+//								setupSquare1100(i,j);
+//						}
+//					}
+//					else
+//					{
+//						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1011(i,j);
+//							else
+//								setupSquare1010(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare1001(i,j);
+//							else
+//								setupSquare1000(i,j);
+//						}
+//					}
+//				}
+//				else
+//				{
+//					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+//					{
+//						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0111(i,j);
+//							else
+//								setupSquare0110(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0101(i,j);
+//							else
+//								setupSquare0100(i,j);
+//						}
+//					}
+//					else
+//					{
+//						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+//						{
+//							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+//								setupSquare0011(i,j);
+//							else
+//								setupSquare0010(i,j);
+//						}
+//						else
+//						{
+//							if(dofVector[neighbourEntities.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)
+	{
+		tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+
+		Real value = dofVector2[Entity.getIndex()];
+		Real im = abs(1.0/map[Entity.getIndex()]);
+		Real a,b, tmp;
+
+		if( i == 0 )
+			a = dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+		else if( i == Mesh.getDimensions().x() - 1 )
+			a = dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+		else
+		{
+			a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+					 dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+		}
+
+		if( j == 0 )
+			b = dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+		else if( j == Mesh.getDimensions().y() - 1 )
+			b = dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+		else
+		{
+			b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+					 dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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..aa606ea47999ce739fb23d7ad6c38f937cf23f26
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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, tnlHost, int >, double, int >* solver, int sweep, int i, int* changed);
+//__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+//__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 3,double, tnlHost, 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 100755
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..217377f3b77645f2ad2ede8db68bdada5f0885fb
--- /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,tnlHost, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		checkCudaDevice;
+	   cout << "-------------------------------------------------------------" << endl;
+	   cout << "Starting solver..." << endl;
+	   solver.run();
+   }
+   else if(dim == 3)
+   {
+		tnlFastSweeping<tnlGrid<3,double,tnlHost, int>, double, int> solver;
+		if(!solver.init(parameters))
+	   {
+			cerr << "Solver failed to initialize." << endl;
+			return EXIT_FAILURE;
+	   }
+		checkCudaDevice;
+	   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..55f145af95deba9752fb5c4f564bbbfa331bf153
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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..48cbba5cb2e247296d41d3b7c2f935c8f75ce960
--- /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();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+	for(int i = 0; i < 2*n ; i++)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+	for(int i = 0; i < 2*n ; i++)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i);
+		cudaDeviceSynchronize();
+	}
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+	for(int i = 2*n - 1; i > -1; i--)
+	{
+		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,i);
+		cudaDeviceSynchronize();
+	}
+
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+	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, tnlHost, 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, tnlHost, 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..e6b20eb4153b04248a3bf72b2198d923aa21d748
--- /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();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+////	for(int i = 0; i < 2*n ; i++)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,0);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	checkCudaDevice;
+////	for(int i = 0; i < 2*n ; i++)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,0);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	checkCudaDevice;
+////	for(int i = 2*n - 1; i > -1; i--)
+//	{
+//		runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,0);
+//		cudaDeviceSynchronize();
+//	}
+//
+//	cudaDeviceSynchronize();
+//	checkCudaDevice;
+
+	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, tnlHost, 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, tnlHost, 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..d05b649f29d222bc96649d3d6ed92a7fa11cf14e
--- /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();
+	checkCudaDevice;
+
+	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();
+//	checkCudaDevice;
+//	for(int i = 0; i < 2*m -1; i++)
+//	{
+//		runCUDA<2><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	checkCudaDevice;
+//	for(int i = 0; i < 2*m -1; i++)
+//	{
+//		runCUDA<4><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i);
+//		cudaDeviceSynchronize();
+//	}
+//	cudaDeviceSynchronize();
+//	checkCudaDevice;
+//	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();
+	checkCudaDevice;
+
+	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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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, tnlHost, 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..230b6ce436bb53c40172eb43cf8b7e668f4bf891
--- /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();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+
+	//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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+				 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+				 cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+			{
+				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1111(i,j);
+					else
+						setupSquare1110(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1101(i,j);
+					else
+						setupSquare1100(i,j);
+				}
+			}
+			else
+			{
+				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1011(i,j);
+					else
+						setupSquare1010(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare1001(i,j);
+					else
+						setupSquare1000(i,j);
+				}
+			}
+		}
+		else
+		{
+			if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+			{
+				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0111(i,j);
+					else
+						setupSquare0110(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0101(i,j);
+					else
+						setupSquare0100(i,j);
+				}
+			}
+			else
+			{
+				if(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+				{
+					if(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+						setupSquare0011(i,j);
+					else
+						setupSquare0010(i,j);
+				}
+				else
+				{
+					if(cudaDofVector[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+//	Entity.setCoordinates(CoordinatesType(i,j));
+//	Entity.refresh();
+//	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+//	cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+//	Entity.setCoordinates(CoordinatesType(i,j));
+//	Entity.refresh();
+//	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+//	cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=INT_MAX;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=INT_MAX;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[Entity.getIndex()]-
+			 cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=INT_MAX;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-INT_MAX;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=0.5*h;	//fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	Real al,be, a,b,c,s;
+	al=abs(cudaDofVector[Entity.getIndex()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 cudaDofVector[Entity.getIndex()]));
+
+	be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 cudaDofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=-0.5*h;	//fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=0.5*h;	//fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.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, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+	cudaDofVector2[Entity.getIndex()]=-0.5*h;	//fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=-0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=0.5*h;	//fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],cudaDofVector2[neighbourEntities.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..f9f3e28f63fc7a3ad88b98980a4454035fd299b4
--- /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();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+
+	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, tnlHost, 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, tnlHost, 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..920806c211483d1c8cc3dabd2e194704dbb560bd
--- /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()
+{
+
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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();
+			neighbourEntities.refresh(Mesh,Entity.getIndex());
+
+				if(dofVector[this->Entity.getIndex()] > 0)
+				{
+					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1111(i,j);
+							else
+								setupSquare1110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1101(i,j);
+							else
+								setupSquare1100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1011(i,j);
+							else
+								setupSquare1010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare1001(i,j);
+							else
+								setupSquare1000(i,j);
+						}
+					}
+				}
+				else
+				{
+					if(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()] > 0)
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0111(i,j);
+							else
+								setupSquare0110(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0101(i,j);
+							else
+								setupSquare0100(i,j);
+						}
+					}
+					else
+					{
+						if(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()] > 0)
+						{
+							if(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()] > 0)
+								setupSquare0011(i,j);
+							else
+								setupSquare0010(i,j);
+						}
+						else
+						{
+							if(dofVector[neighbourEntities.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();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1,  0 >()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()];
+	else
+	{
+		b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  -1 >()],
+				 dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+//	dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+//	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[Entity.getIndex()]-
+			 dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	Real al,be, a,b,c,s;
+	al=abs(dofVector[Entity.getIndex()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()]-
+			 dofVector[Entity.getIndex()]));
+
+	be=abs(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()]/
+			(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()]-
+			 dofVector[neighbourEntities.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[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.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 neighbourEntities =  Entity.getNeighbourEntities();
+	dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]);
+	dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1,  1 >()]);
+	dofVector2[neighbourEntities.template getEntityIndex< 1,  0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1,  0 >()],dofVector2[neighbourEntities.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..da045676ae1f119e73cc4539732b31d5d632ca23
--- /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();
+	checkCudaDevice;
+	initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+	cudaDeviceSynchronize();
+	checkCudaDevice;
+
+	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();
+	checkCudaDevice;
+
+	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, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh);
+	Entity.setCoordinates(CoordinatesType(i,j,k));
+	Entity.refresh();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity);
+	Real value = cudaDofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0 >()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()],
+				 cudaDofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0 >()] );
+	}
+
+	if( j == 0 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0 >()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()];
+	else
+	{
+		b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0 >()],
+				 cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0 >()] );
+	}
+
+	if( k == 0 )
+		c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  1 >()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()];
+	else
+	{
+		c = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1 >()],
+				 cudaDofVector2[neighbourEntities.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, tnlHost, 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, tnlHost, 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, tnlHost, 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..dd5681e6d88b3fa666f210d0fe24f2423ac78b68
--- /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();
+	tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity);
+	Real value = dofVector2[Entity.getIndex()];
+	Real a,b,c, tmp;
+
+	if( i == 0 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0>()];
+	else if( i == Mesh.getDimensions().x() - 1 )
+		a = dofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0 >()];
+	else
+	{
+		a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1,  0,  0>()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 1,  0,  0>()] );
+	}
+
+	if( j == 0 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0>()];
+	else if( j == Mesh.getDimensions().y() - 1 )
+		b = dofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0>()];
+	else
+	{
+		b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  -1,  0>()],
+				 dofVector2[neighbourEntities.template getEntityIndex< 0,  1,  0>()] );
+	}
+
+	if( k == 0 )
+		c = dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  1>()];
+	else if( k == Mesh.getDimensions().z() - 1 )
+		c = dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1>()];
+	else
+	{
+		c = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0,  0,  -1>()],
+				 dofVector2[neighbourEntities.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..310cdf3f3028eb68e71c31d821ffea1538615724
--- /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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <core/tnlHost.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 tnlVector< 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 tnlVector< 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, tnlHost, int >, double, int >* solver, int sweep, int i);
+__global__ void runCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i);
+
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver);
+__global__ void initCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, 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 100755
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..55a0942f81721c1e90e670aaae18941471f6e13d
--- /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 = tnlHostDevice;
+
+	const int& dim = parameters.getParameter< int >( "dim" );
+
+	if(dim == 2)
+	{
+
+	   typedef parallelGodunovMapScheme< tnlGrid<2,double,tnlHost, 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,tnlHost, int>, double, int > SchemeTypeDevice;
+/*#endif*/
+
+	   if(device==tnlHostDevice)
+	   {
+		   typedef tnlHost 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..bf0a388166c89946727b95687eca1a74764739c3
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
@@ -0,0 +1,218 @@
+/***************************************************************************
+                          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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <core/tnlHost.h>
+#include <mesh/tnlGrid.h>
+#include <mesh/grids/tnlGridEntity.h>
+#include <limits.h>
+#include <core/tnlDevice.h>
+
+
+#include <ctime>
+
+#ifdef HAVE_CUDA
+#include <cuda.h>
+#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 tnlVector< double, tnlHost, int > VectorType;
+	typedef tnlVector< int, tnlHost, int > IntVectorType;
+	typedef tnlGrid< 2, double, tnlHost, int > MeshType;
+#ifdef HAVE_CUDA
+	typedef tnlVector< double, tnlHost, int > VectorTypeCUDA;
+	typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA;
+	typedef tnlGrid< 2, double, tnlHost, 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..1cb730e42d0b0b72782e61e011b6081d2eddc6ef
--- /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 = tnlHostDevice;  /////////////// tnlCuda Device --- vypocet na GPU, tnlHostDevice   ---    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();
+		checkCudaDevice;
+
+		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();
+		checkCudaDevice;
+
+		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();
+		checkCudaDevice;
+
+	}
+#endif
+
+	if(this->device == tnlHostDevice)
+	{
+		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();
+		checkCudaDevice;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		initRunCUDA2D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+
+	}
+#endif
+
+
+	this->currentStep = 1;
+	if(this->device == tnlHostDevice)
+		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();
+		checkCudaDevice;
+		synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+	}
+
+#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 == tnlHostDevice)
+	{
+		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();
+		checkCudaDevice;
+
+		bool* tmpb;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+
+		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();
+			checkCudaDevice;
+			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();
+			checkCudaDevice;
+			synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			//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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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();
+			neighbourEntities.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,neighbourEntities,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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<2,int>(i,j));
+   Entity.refresh();
+   neighbourEntities.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, neighbourEntities, 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 100755
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..3a976dae469a77dc33559cf562f722913de0ef28
--- /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 = tnlHostDevice;
+
+   const int& dim = parameters.getParameter< int >( "dim" );
+
+  if(dim == 2)
+  {
+
+	   typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlHost, 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,tnlHost, int>, double, int > SchemeTypeDevice;
+		/*#endif*/
+
+	   if(device==tnlHostDevice)
+	   {
+		   typedef tnlHost 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,tnlHost, 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,tnlHost, int>, double, int > SchemeTypeDevice;
+		/*#endif*/
+
+	   if(device==tnlHostDevice)
+	   {
+		   typedef tnlHost 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..f79752b7187cf9de4f58299fa9add9ce72f2c407
--- /dev/null
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
@@ -0,0 +1,367 @@
+/***************************************************************************
+                          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 <core/vectors/tnlVector.h>
+#include <TNL/Containers/StaticVector.h>
+#include <functions/tnlMeshFunction.h>
+#include <core/tnlHost.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 <cuda.h>
+#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 tnlVector< double, tnlHost, int > VectorType;
+	typedef tnlVector< int, tnlHost, int > IntVectorType;
+	typedef tnlGrid< 2, double, tnlHost, int > MeshType;
+#ifdef HAVE_CUDA
+	typedef tnlVector< double, tnlHost, int > VectorTypeCUDA;
+	typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA;
+	typedef tnlGrid< 2, double, tnlHost, 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, tnlHost, 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 tnlVector< double, tnlHost, int > VectorType;
+		typedef tnlVector< int, tnlHost, int > IntVectorType;
+		typedef tnlGrid< 3, double, tnlHost, int > MeshType;
+	#ifdef HAVE_CUDA
+		typedef tnlVector< double, tnlHost, int > VectorTypeCUDA;
+		typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA;
+		typedef tnlGrid< 3, double, tnlHost, 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, tnlHost, 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..6279fbb805733172ebda8a78c68a128d0d33f92c
--- /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, tnlHostDevice   ---    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();
+	checkCudaDevice;
+	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();
+	checkCudaDevice;
+	//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();
+	checkCudaDevice;
+	//cout << "s "<< endl;
+
+	}
+#endif
+
+	if(this->device == tnlHostDevice)
+	{
+	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();
+		checkCudaDevice;
+		dim3 threadsPerBlock(this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		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 == tnlHostDevice)
+		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;
+
+		checkCudaDevice;
+
+		synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		//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);
+		//checkCudaDevice;
+		//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 == tnlHostDevice)
+	{
+
+	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();
+		checkCudaDevice;
+		//cudaMalloc(&runcuda,sizeof(bool));
+		//cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice);
+		//cout << "fn" << endl;
+		bool* tmpb;
+		//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+		//cudaDeviceSynchronize();
+		//checkCudaDevice;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		//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();
+			checkCudaDevice;
+			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();
+			checkCudaDevice;
+			synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			//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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(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();
+			neighbourEntities.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,neighbourEntities);
+      }
+      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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<2,int>(i,j));
+   Entity.refresh();
+   neighbourEntities.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, neighbourEntities);
+
+	  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..12d9003099643c923fdd6f4be18f2b07b35ebf3d
--- /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 = tnlHostDevice;  /////////////// tnlCuda Device --- vypocet na GPU, tnlHostDevice   ---    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();
+	checkCudaDevice;
+	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();
+	checkCudaDevice;
+	//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();
+	checkCudaDevice;
+	//cout << "s "<< endl;
+
+	}
+#endif
+
+	if(this->device == tnlHostDevice)
+	{
+#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();
+		checkCudaDevice;
+		dim3 threadsPerBlock(this->n, this->n, this->n);
+		dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		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 == tnlHostDevice)
+		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;
+
+		checkCudaDevice;
+
+		synchronizeCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver);
+		cout << cudaGetErrorString(cudaDeviceSynchronize()) << endl;
+		checkCudaDevice;
+		synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		//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);
+		//checkCudaDevice;
+		//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 == tnlHostDevice)
+	{
+
+	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();
+		checkCudaDevice;
+		//cudaMalloc(&runcuda,sizeof(bool));
+		//cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice);
+		//cout << "fn" << endl;
+		bool* tmpb;
+		//cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost);
+		//cudaDeviceSynchronize();
+		//checkCudaDevice;
+		cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost);
+		cudaDeviceSynchronize();
+		checkCudaDevice;
+		//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();
+			checkCudaDevice;
+			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();
+			checkCudaDevice;
+			synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver);
+			cudaDeviceSynchronize();
+			checkCudaDevice;
+			//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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(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;
+			neighbourEntities.refresh(subMesh,Entity.getIndex());
+//			cout << "e" <<endl;
+    	  fu[ i ] = schemeHost.getValue( this->subMesh, i, coords,u, time, boundaryCondition, neighbourEntities );
+//    	  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);
+   tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity);
+   Entity.setCoordinates(Containers::StaticVector<3,int>(i,j,k));
+   Entity.refresh();
+   neighbourEntities.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, neighbourEntities);
+		  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 100755
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..a4182050ac311e21be33388ff22fded1428a88a0
--- /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 <core/vectors/tnlVector.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 getExplicitRHS( 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..af1d427597ffe71d606bd3ca60f206470dcf2c92
--- /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::getMeshDimensions();
+
+   if( Dimensions <= 0 || Dimensions > 3 )
+   {
+      cerr << "The problem is not defined for " << Dimensions << "dimensions." << endl;
+      return false;
+   }
+   else
+   {
+      typedef Containers::StaticVector < Dimensions, RealType > Vertex;
+      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..9917205ead68b98de8b55d8423042a99fb0848dd
--- /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 >::
+getExplicitRHS(  const RealType& time,
+                 const RealType& tau,
+                 const MeshType& mesh,
+                 DofVectorType& _u,
+                 DofVectorType& _fu,
+                 MeshDependentDataType& meshDependentData  )
+{
+
+	/*
+	if(!(this->schemeTest))
+		scheme.GetExplicitRHS(time, tau, _u, _fu);
+	else if(!(this->tested))
+	{
+		this->tested = true;
+		DofVectorType tmp;
+		if(tmp.setLike(_u))
+			tmp = _u;
+		scheme.GetExplicitRHS(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..a36153011e3b2e8b8e5590a27e1c0bdcf895faf5
--- /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 > Vertex;
+
+   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..c2983fac2c12e1b7791bd86973a712a5fcc6c948
--- /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& neighbours = cell.getNeighbourEntities();
+         //const IndexType& c = cell.getIndex();
+         const IndexType e = neighbours.template getEntityIndex<  1 >();
+         const IndexType w = neighbours.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 neighbours = cell.getNeighbourEntities();
+            const IndexType e = neighbours.template getEntityIndex<  1,  0 >();
+            const IndexType w = neighbours.template getEntityIndex< -1,  0 >();
+            const IndexType n = neighbours.template getEntityIndex<  0,  1 >();
+            const IndexType s = neighbours.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& neighbourEntities = cell.template getNeighbourEntities< 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[ neighbourEntities.template getEntityIndex< 1,  0 >() ];
+   else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 )
+      a = u[ neighbourEntities.template getEntityIndex< -1,  0 >() ];
+   else
+   {
+      a = ArgAbsMin( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ],
+                     u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] );
+   }
+
+   if( cell.getCoordinates().y() == 0 )
+      b = u[ neighbourEntities.template getEntityIndex< 0,  1 >()];
+   else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 )
+      b = u[ neighbourEntities.template getEntityIndex< 0,  -1 >() ];
+   else
+   {
+      b = ArgAbsMin( u[ neighbourEntities.template getEntityIndex< 0,  -1 >() ],
+                     u[ neighbourEntities.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 neighbours = cell.getNeighbourEntities();
+               //const IndexType& c = cell.getIndex();
+               const IndexType e = neighbours.template getEntityIndex<  1,  0,  0 >();
+               const IndexType w = neighbours.template getEntityIndex< -1,  0,  0 >();
+               const IndexType n = neighbours.template getEntityIndex<  0,  1,  0 >();
+               const IndexType s = neighbours.template getEntityIndex<  0, -1,  0 >();
+               const IndexType t = neighbours.template getEntityIndex<  0,  0,  1 >();
+               const IndexType b = neighbours.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..04332b0f6c398adb36e2df4c338775575dbbcc9e
--- /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::getMeshDimensions(), 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, tnlHost >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef tnlHost 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, tnlHost >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef tnlHost 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, tnlHost >::value, "The fast sweeping method works only on CPU." );
+   
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef Real RealType;
+      typedef tnlHost 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/File.h b/src/TNL/File.h
index 9ea11d299a1d160eec562d156ab35d9c9112b8f4..1eea42eae61b67867bfeb7218b0a1801932f2c14 100644
--- a/src/TNL/File.h
+++ b/src/TNL/File.h
@@ -119,4 +119,3 @@ bool fileExists( const String& fileName );
 } // namespace TNL
 
 #include <TNL/File_impl.h>
-
diff --git a/src/TNL/Functions/Analytic/Blob.h b/src/TNL/Functions/Analytic/Blob.h
index 56c6e22b7eab001f03b45137b23ba6f2582d4798..c436254d6af11f4563a2eb49db8f33149f4bdd8e 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
diff --git a/src/TNL/Functions/Analytic/Blob_impl.h b/src/TNL/Functions/Analytic/Blob_impl.h
index c6d969d38527cfab69858a39f3d2fac3b340287e..00328818b266d1e9c40674e3701c86116391a9c4 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
diff --git a/src/TNL/Functions/Analytic/CMakeLists.txt b/src/TNL/Functions/Analytic/CMakeLists.txt
index 01c91a1542b9b1cfdbb1bae7c2e37c4ce44fdb91..744345453d919ac82f2ef2a39186774f90c1b652 100755
--- 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..8e20cc6d5c816149e0422e615e499390d16bcaa7 100644
--- a/src/TNL/Functions/Analytic/Constant.h
+++ b/src/TNL/Functions/Analytic/Constant.h
@@ -44,7 +44,7 @@ class Constant : public Domain< dimensions, NonspaceDomain >
                 int YDiffOrder,
                 int ZDiffOrder >
    #else
-      template< int XDiffOrder,
+      template< int XDiffOrder = 0,
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
    #endif
diff --git a/src/TNL/Functions/Analytic/Paraboloid.h b/src/TNL/Functions/Analytic/Paraboloid.h
new file mode 100644
index 0000000000000000000000000000000000000000..e07963155dbcf2a8c9d54028c7e3846c1100be2f
--- /dev/null
+++ b/src/TNL/Functions/Analytic/Paraboloid.h
@@ -0,0 +1,168 @@
+/***************************************************************************
+                          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 > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const
+      {
+         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 > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const
+      {
+         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 > VertexType;
+
+
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const
+      {
+         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..4d3177e365cfd46b45d57064d39e57ee163fd74a
--- /dev/null
+++ b/src/TNL/Functions/Analytic/ParaboloidSDF.h
@@ -0,0 +1,160 @@
+/***************************************************************************
+                          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 > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class ParaboloidSDF< 2, Real > : public ParaboloidSDFBase< 2, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class ParaboloidSDF< 3, Real > : public ParaboloidSDFBase< 3, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > VertexType;
+
+
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< int Dimensions,
+          typename Real >
+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..a4c1be5a03c72943502974ae7987139b791c6c9c
--- /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 VertexType& 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 VertexType& 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 VertexType& 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..24b8a7a6aa5cdbbcf4496678c2f5c4e12fc7b63e
--- /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 VertexType& 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 VertexType& 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 VertexType& 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..7f58906597338b78588cdf6e40940bd6b3b87d0b 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
diff --git a/src/TNL/Functions/Analytic/PseudoSquare_impl.h b/src/TNL/Functions/Analytic/PseudoSquare_impl.h
index 378e11ac11c720b573a46d922b4d66cdb63ee66b..ab81b85f0b3144f4cb8507f8a83cdfd1dbedf097 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
diff --git a/src/TNL/Functions/Analytic/SDFSchemeTest.h b/src/TNL/Functions/Analytic/SDFSchemeTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3720fcb12f2a70c0593a1eafe7eeb8d00a58b0c
--- /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 Vertex VertexType;
+   typedef typename VertexType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const VertexType& 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 Vertex VertexType;
+   typedef typename VertexType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const VertexType& 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 Vertex VertexType;
+   typedef typename VertexType::RealType RealType;
+
+   template< int XDiffOrder = 0,
+             int YDiffOrder = 0,
+             int ZDiffOrder = 0 >
+   RealType getValue( const VertexType& 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..c2be9ef3433847562134f29aff2680d410378e3b
--- /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 Vertex& 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 Vertex& 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 Vertex& 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..ea37dec8e547f4a11b1b9c422ab6fe78b8694a20 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>
@@ -39,11 +43,15 @@ class SinBumpsBase : public Domain< Vertex::size, SpaceDomain >
 
       const VertexType& getPhase() const;
 
+      void setWavesNumber( const VertexType& wavesNumber );
+
+      const VertexType& getWavesNumber() const;
+
    protected:
 
       RealType amplitude;
 
-      VertexType waveLength, phase;
+      VertexType waveLength, phase, wavesNumber;
 };
 
 template< int Dimensions, typename Real >
@@ -59,7 +67,6 @@ class SinBumps< 1, Real  > : public SinBumpsBase< Containers::StaticVector< 1, R
       typedef Real RealType;
       typedef Containers::StaticVector< 1, RealType > VertexType;
 
-
       SinBumps();
 
       bool setup( const Config::ParameterContainer& parameters,
@@ -91,7 +98,6 @@ class SinBumps< 2, Real > : public SinBumpsBase< Containers::StaticVector< 2, Re
 
       typedef Real RealType;
       typedef Containers::StaticVector< 2, RealType > VertexType;
- 
 
       SinBumps();
 
@@ -163,4 +169,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..e402872d27958478e5adca8a0d17e6f24e12fa2e
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinBumpsSDF.h
@@ -0,0 +1,172 @@
+/***************************************************************************
+                          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 Vertex >
+class SinBumpsSDFBase : public Domain< Vertex::size, SpaceDomain >
+{
+   public:
+
+      typedef Vertex VertexType;
+      typedef typename Vertex::RealType RealType;
+      enum { Dimensions = VertexType::size };
+
+      void setWaveLength( const VertexType& waveLength );
+
+      const VertexType& getWaveLength() const;
+
+      void setAmplitude( const RealType& amplitude );
+
+      const RealType& getAmplitude() const;
+
+      void setPhase( const VertexType& phase );
+
+      const VertexType& getPhase() const;
+
+      void setWavesNumber( const VertexType& wavesNumber );
+
+      const VertexType& getWavesNumber() const;
+
+   protected:
+
+      RealType amplitude;
+
+      VertexType 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 > VertexType;
+
+
+      SinBumpsSDF();
+
+      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,
+                                     const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const VertexType& 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 > VertexType;
+
+
+      SinBumpsSDF();
+
+      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,
+                                     const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const VertexType& 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 > VertexType;
+
+      SinBumpsSDF();
+
+      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,
+                         const Real& time = 0.0 ) const;
+
+   __cuda_callable__
+   RealType operator()( const VertexType& 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..6b38ae51238dfdca01404bcbb4002a663f409211
--- /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 Vertex >
+void SinBumpsSDFBase< Vertex >::setWaveLength( const Vertex& waveLength )
+{
+   this->waveLength = waveLength;
+}
+
+template< typename Vertex >
+const Vertex& SinBumpsSDFBase< Vertex >::getWaveLength() const
+{
+   return this->waveLength;
+}
+
+template< typename Vertex >
+void SinBumpsSDFBase< Vertex >::setAmplitude( const typename Vertex::RealType& amplitude )
+{
+   this->amplitude = amplitude;
+}
+
+template< typename Vertex >
+const typename Vertex::RealType& SinBumpsSDFBase< Vertex >::getAmplitude() const
+{
+   return this->amplitude;
+}
+
+template< typename Vertex >
+void SinBumpsSDFBase< Vertex >::setPhase( const Vertex& phase )
+{
+   this->phase = phase;
+}
+
+template< typename Vertex >
+const Vertex& SinBumpsSDFBase< Vertex >::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 VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   RealType xp = ::fabs( 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 VertexType& 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 VertexType& 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
\ No newline at end of file
diff --git a/src/TNL/Functions/Analytic/SinBumps_impl.h b/src/TNL/Functions/Analytic/SinBumps_impl.h
index 8ae3eeb6abdce64ee0db3df89c5e59ada351f58b..337b7db27296a1f72ae3d874f93a6979fb4fc434 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>
@@ -52,10 +55,21 @@ const Vertex& SinBumpsBase< Vertex >::getPhase() const
    return this->phase;
 }
 
+template< typename Vertex >
+void SinBumpsBase< Vertex >::setWavesNumber( const Vertex& wavesNumber )
+{
+   this->wavesNumber = wavesNumber;
+}
+
+template< typename Vertex >
+const Vertex& SinBumpsBase< Vertex >::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;
 }
 
@@ -82,9 +97,14 @@ SinBumps< 1, Real >::
 getPartialDerivative( const VertexType& 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 = ::fabs( 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 )
@@ -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,
@@ -137,10 +157,18 @@ SinBumps< 2, Real>::
 getPartialDerivative( const VertexType& 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 = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = ::fabs( 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() ) *
@@ -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,
@@ -205,6 +234,16 @@ getPartialDerivative( const VertexType& v,
    const RealType& x = v.x();
    const RealType& y = v.y();
    const RealType& z = v.z();
+   
+   const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = ::fabs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+   const RealType zp = ::fabs( 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() ) *
diff --git a/src/TNL/Functions/Analytic/SinWave.h b/src/TNL/Functions/Analytic/SinWave.h
index 98c8cdddc6e8f9d0a0433fca653ade91d5d85665..24549851fa98a8817e28430f909ad99e497811f8 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,26 +27,32 @@ 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 >
@@ -140,7 +149,8 @@ std::ostream& operator << ( std::ostream& str, const SinWave< Dimensions, Real >
 {
    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..29278c35878b7b5c8f5eba6630959ee80b8df75f
--- /dev/null
+++ b/src/TNL/Functions/Analytic/SinWaveSDF.h
@@ -0,0 +1,159 @@
+/***************************************************************************
+                          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 > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinWaveSDF< 2, Real > : public SinWaveSDFBase< 2, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 2, RealType > VertexType;
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< typename Real >
+class SinWaveSDF< 3, Real > : public SinWaveSDFBase< 3, Real >
+{
+   public:
+
+      typedef Real RealType;
+      typedef Containers::StaticVector< 3, RealType > VertexType;
+
+
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                         const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+
+};
+
+template< int Dimensions,
+          typename Real >
+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..5d010df173f833e1d480c28a92886ada7c59e460
--- /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 VertexType& 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( false, std::cerr << "TODO: implement this" );
+   return 0.0;
+}
+
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+SinWaveSDF< 2, Real >::
+getPartialDerivative( const VertexType& 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( false, std::cerr << "TODO: implement this" );
+   return 0.0;
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder>
+__cuda_callable__
+Real
+SinWaveSDF< 3, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   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( false, std::cerr << "TODO: implement this" );
+   return 0.0;
+}
+
+      } // namespace Analytic
+   } // namespace Functions
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/Twins.h b/src/TNL/Functions/Analytic/Twins.h
index ebdb507ac79e84681396715254ff4d4e30ff1b9e..d6627cdef82b7f28e69b202c48fe9bd1f91870ed 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
diff --git a/src/TNL/Functions/Analytic/Twins_impl.h b/src/TNL/Functions/Analytic/Twins_impl.h
index 222f9a452adf289bcc9282c75cf2014ecc23c289..2b294320fed642d15cc9b2d7355ff2aa3f7f7a02 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
diff --git a/src/TNL/Functions/Analytic/VectorNorm.h b/src/TNL/Functions/Analytic/VectorNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..7dd48b1a320c62d222934ed71d8481cb64ef1da1
--- /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 > VertexType;
+ 
+      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 VertexType& center )
+      {
+         this->center = center;
+      };
+
+      const RealType& getCenter() const
+      {
+         return this->center;
+      }
+      
+      void setAnisotropy( const VertexType& 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:
+
+      VertexType 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::VertexType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& 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 VertexType& 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::VertexType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__ inline
+      RealType getPartialDerivative( const VertexType& 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( false, std::cerr << "Not implemented yet." << std::endl );
+         return 0.0;
+      }
+ 
+      __cuda_callable__
+      RealType operator()( const VertexType& 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::VertexType;
+
+      static String getType();
+
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& 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( false, std::cerr << "Not implemented yet." << std::endl );
+         return 0.0;
+      }
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& 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
index 04fe4b86805ddbdd11f0d9a73492918db7baeb5d..7727d5539ffb2a475e3c27f3b71b6ba997a23f52 100755
--- 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/MeshFunction.h b/src/TNL/Functions/MeshFunction.h
index a3cf8a46c307312ff0e10127da53339c48ddb3e4..35fee42d13beb047bc4d11b108edeb0ca1890f08 100644
--- a/src/TNL/Functions/MeshFunction.h
+++ b/src/TNL/Functions/MeshFunction.h
@@ -84,7 +84,6 @@ class MeshFunction :
                  const SharedPointer< Vector >& dataPtr,
                  const IndexType& offset = 0 );
       
-      
       void setMesh( const MeshPointer& meshPointer );
       
       template< typename Device = Devices::Host >
@@ -93,6 +92,8 @@ class MeshFunction :
       
       const MeshPointer& getMeshPointer() const;
       
+      __cuda_callable__ static IndexType getDofs( const MeshPointer& meshPointer );
+      
       __cuda_callable__ const VectorType& getData() const;      
       
       __cuda_callable__ VectorType& getData();
@@ -144,7 +145,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;
  
diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter.h b/src/TNL/Functions/MeshFunctionGnuplotWriter.h
index 887498711e8f3e4422a7cc99994cfecc2301504d..2c21a10328d4bd49bb6f3501246ce476cca83bd2 100644
--- a/src/TNL/Functions/MeshFunctionGnuplotWriter.h
+++ b/src/TNL/Functions/MeshFunctionGnuplotWriter.h
@@ -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,7 +61,8 @@ 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 );
 };
 
 
@@ -78,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 );
 };
 
 /***
@@ -96,7 +100,8 @@ 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 );
 };
 
 /***
@@ -114,7 +119,8 @@ 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 );
 };
 
 
@@ -133,7 +139,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 3, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 /***
@@ -151,7 +158,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 /***
@@ -169,7 +177,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device
       typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType;
 
       static bool write( const MeshFunctionType& function,
-                         std::ostream& str );
+                         std::ostream& str,
+                         const double& scale );
 };
 
 } // namespace Functions
diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
index 341ed711a4cb4da60f3f6501a5dec0f8b736925a..9c442de639194e909ca5d3f54c491eede082f945 100644
--- a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
+++ b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
@@ -19,7 +19,8 @@ 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;
@@ -35,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 );
@@ -46,7 +48,7 @@ write( const MeshFunctionType& function,
       entity.refresh();
       typename MeshType::VertexType v = entity.getCenter();
       str << v.x() << " "
-          << function.getData().getElement( entity.getIndex() ) << std::endl;
+          << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
 }
@@ -61,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 );
@@ -72,7 +75,7 @@ write( const MeshFunctionType& function,
       entity.refresh();
       typename MeshType::VertexType v = entity.getCenter();
       str << v.x() << " "
-          << function.getData().getElement( entity.getIndex() ) << std::endl;
+          << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
 }
@@ -88,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 );
@@ -103,7 +107,7 @@ write( const MeshFunctionType& function,
          entity.refresh();
          typename MeshType::VertexType 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;
    }
@@ -120,7 +124,8 @@ 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;
@@ -139,7 +144,7 @@ write( const MeshFunctionType& function,
          entity.refresh();
          typename MeshType::VertexType 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;
    }
@@ -158,7 +163,7 @@ write( const MeshFunctionType& function,
          entity.refresh();
          typename MeshType::VertexType 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;
    }
@@ -176,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 );
@@ -191,7 +197,7 @@ write( const MeshFunctionType& function,
          entity.refresh();
          typename MeshType::VertexType 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;
    }
@@ -209,7 +215,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typename MeshType::Cell entity( mesh );
@@ -227,7 +234,7 @@ write( const MeshFunctionType& function,
             entity.refresh();
             typename MeshType::VertexType v = entity.getCenter();
             str << v.x() << " " << v.y() << " " << v.z() << " "
-                << function.getData().getElement( entity.getIndex() ) << std::endl;
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
          }
          str << std::endl;
       }
@@ -244,7 +251,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
 write( const MeshFunctionType& function,
-       std::ostream& str )
+       std::ostream& str,
+       const double& scale )
 {
    const MeshType& mesh = function.getMesh();
    typedef typename MeshType::Face EntityType;
@@ -266,7 +274,7 @@ write( const MeshFunctionType& function,
             entity.refresh();
             typename MeshType::VertexType v = entity.getCenter();
             str << v.x() << " " << v.y() << " " << v.z() << " "
-                << function.getData().getElement( entity.getIndex() ) << std::endl;
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
          }
          str << std::endl;
       }
@@ -286,7 +294,7 @@ write( const MeshFunctionType& function,
             entity.refresh();
             typename MeshType::VertexType v = entity.getCenter();
             str << v.x() << " " << v.y() << " " << v.z() << " "
-                << function.getData().getElement( entity.getIndex() ) << std::endl;
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
          }
          str << std::endl;
       }
@@ -306,7 +314,7 @@ write( const MeshFunctionType& function,
             entity.refresh();
             typename MeshType::VertexType v = entity.getCenter();
             str << v.x() << " " << v.y() << " " << v.z() << " "
-                << function.getData().getElement( entity.getIndex() ) << std::endl;
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
          }
          str << std::endl;
       }
@@ -324,7 +332,8 @@ template< typename MeshReal,
 bool
 MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, 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 );
@@ -342,7 +351,7 @@ write( const MeshFunctionType& function,
             entity.refresh();
             typename MeshType::VertexType v = entity.getCenter();
             str << v.x() << " " << v.y() << " " << v.z() << " "
-                << function.getData().getElement( entity.getIndex() ) << std::endl;
+                << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
          }
          str << std::endl;
       }
diff --git a/src/TNL/Functions/MeshFunctionVTKWriter.h b/src/TNL/Functions/MeshFunctionVTKWriter.h
index 39651c27450c407639c1278f62220b82f51f240b..b4d18e4490901c2824ff922fe10f18607198e780 100644
--- a/src/TNL/Functions/MeshFunctionVTKWriter.h
+++ b/src/TNL/Functions/MeshFunctionVTKWriter.h
@@ -23,7 +23,9 @@ 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 ){}
 };
@@ -43,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 );
 };
@@ -63,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 );
 };
@@ -83,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 );
 };
@@ -103,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 );
 };
@@ -123,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 );
 };
@@ -143,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 );
 };
@@ -163,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 );
 };
@@ -183,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 );
 };
@@ -203,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 );
 };
diff --git a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
index b432671764c0545c64e5c8ea241c820525f20f05..91a589bbe81c6261b0ee61882a3b03824d970b62 100644
--- a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
+++ b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h
@@ -19,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;
@@ -54,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);
  
@@ -88,7 +90,7 @@ write( const MeshFunctionType& function,
    {
       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;
@@ -123,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);
  
@@ -157,7 +160,7 @@ write( const MeshFunctionType& function,
    {
       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;
@@ -192,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);
  
@@ -237,7 +241,7 @@ write( const MeshFunctionType& function,
    {
       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;
@@ -272,7 +276,8 @@ 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;
@@ -326,7 +331,7 @@ write( const MeshFunctionType& function,
    {
       typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i );
       entity.refresh();
-      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
 
    return true;
@@ -361,7 +366,8 @@ 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;
    writeHeader(function, str);
@@ -405,7 +411,7 @@ write( const MeshFunctionType& function,
    {
       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;
@@ -440,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);
  
@@ -501,7 +508,7 @@ write( const MeshFunctionType& function,
    {
       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;
@@ -536,7 +543,8 @@ 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 )
 {
    writeHeader(function, str);
  
@@ -620,7 +628,7 @@ write( const MeshFunctionType& function,
    {
       typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i );
       entity.refresh();
-      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
 
    return true;
@@ -655,7 +663,8 @@ 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 )
 {
    writeHeader(function, str);
  
@@ -733,7 +742,7 @@ write( const MeshFunctionType& function,
    {
       typename MeshType::Edge entity = mesh.template getEntity< typename MeshType::Edge >( i );
       entity.refresh();
-      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+      str << scale * function.getData().getElement( entity.getIndex() ) << std::endl;
    }
 
    return true;
@@ -768,7 +777,8 @@ 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 )
 {
    writeHeader(function, str);
  
@@ -820,7 +830,7 @@ write( const MeshFunctionType& function,
    {
       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;
diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h
index 53ab95680738b8ee77c7a76ca7de9e7344f3f3a8..8f365c4d88a9993ee1c28a74fc0547d7f02cb8f4 100644
--- a/src/TNL/Functions/MeshFunction_impl.h
+++ b/src/TNL/Functions/MeshFunction_impl.h
@@ -163,6 +163,7 @@ setup( const MeshPointer& meshPointer,
    else
    {
       std::cerr << "Missing parameter " << prefix << "file." << std::endl;
+      throw(0);
       return false;
    }
    return true;
@@ -250,6 +251,17 @@ getMeshPointer() const
    return this->meshPointer;
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+__cuda_callable__
+typename MeshFunction< Mesh, MeshEntityDimensions, Real >::IndexType
+MeshFunction< Mesh, MeshEntityDimensions, Real >::
+getDofs( const MeshPointer& meshPointer )
+{
+   return meshPointer->template getEntitiesCount< MeshEntityDimensions >();
+}
+
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
@@ -482,19 +494,20 @@ template< typename Mesh,
 bool
 MeshFunction< Mesh, MeshEntityDimensions, 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 );
+      return MeshFunctionVTKWriter< ThisType >::write( *this, file, scale );
    else if( format == "gnuplot" )
-      return MeshFunctionGnuplotWriter< ThisType >::write( *this, file );
+      return MeshFunctionGnuplotWriter< ThisType >::write( *this, file, scale );
    else {
       std::cerr << "Unknown output format: " << format << std::endl;
       return false;
diff --git a/src/TNL/Functions/OperatorFunction.h b/src/TNL/Functions/OperatorFunction.h
index 628191165d38d3ae12052091e15b01ba43e852b7..4eaf24156e0152ac8d74210cef3c3c83752f1c38 100644
--- a/src/TNL/Functions/OperatorFunction.h
+++ b/src/TNL/Functions/OperatorFunction.h
@@ -30,18 +30,19 @@ 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 Function,
           typename BoundaryConditions >
-class OperatorFunction< Operator, MeshFunction, BoundaryConditions, true >
+class OperatorFunction< Operator, Function, BoundaryConditions, true, false >
  : public Domain< Operator::getMeshDimensions(), MeshDomain >
 {
 };
@@ -50,21 +51,21 @@ 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 >
+          typename Function >
+class OperatorFunction< Operator, Function, void, true, false >
  : public Domain< Operator::getDomainDimensions(), 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." );
-      static_assert( std::is_same< typename Operator::MeshType, typename MeshFunctionT::MeshType >::value,
+      static_assert( Function::getDomainType() == MeshDomain ||
+                     Function::getDomainType() == MeshInteriorDomain ||
+                     Function::getDomainType() == MeshBoundaryDomain,
+         "Only mesh preimageFnctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." );
+      static_assert( std::is_same< typename Operator::MeshType, typename Function::MeshType >::value,
           "Both, operator and mesh preimageFunction must be defined on the same mesh." );
  
       typedef Operator OperatorType;
-      typedef MeshFunctionT FunctionType;
+      typedef Function FunctionType;
       typedef typename OperatorType::MeshType MeshType;
       typedef typename OperatorType::RealType RealType;
       typedef typename OperatorType::DeviceType DeviceType;
@@ -90,7 +91,7 @@ class OperatorFunction< Operator, MeshFunctionT, void, true >
       
       const MeshPointer& getMeshPointer() const
       { 
-         tnlTNL_ASSERT( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         TNL_ASSERT( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
          return this->preimageFunction->getMeshPointer(); 
       };
 
@@ -128,17 +129,17 @@ 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 >
+          typename Function >
+class OperatorFunction< Operator, Function, void, false, false >
  : public Domain< Operator::getDomainDimensions(), Operator::getDomainType() >
 {
    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." );
  
       typedef Operator OperatorType;
@@ -146,9 +147,9 @@ class OperatorFunction< Operator, PreimageFunction, void, false >
       typedef typename OperatorType::RealType RealType;
       typedef typename OperatorType::DeviceType DeviceType;
       typedef typename OperatorType::IndexType IndexType;
-      typedef PreimageFunction PreimageFunctionType;
+      typedef Function PreimageFunctionType;
       typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
-      typedef OperatorFunction< Operator, PreimageFunction, void, true > OperatorFunctionType;
+      typedef OperatorFunction< Operator, Function, void, true > OperatorFunctionType;
       typedef typename OperatorType::ExactOperatorType ExactOperatorType;
       typedef SharedPointer< MeshType, DeviceType > MeshPointer;
       
@@ -172,7 +173,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 +233,18 @@ class OperatorFunction< Operator, PreimageFunction, void, false >
  * Specialization for precomputed evaluation and with boundary conditions.
  */
 template< typename Operator,
-          typename PreimageFunction,
+          typename Function,
           typename BoundaryConditions >
-class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
+class OperatorFunction< Operator, Function, BoundaryConditions, false, false >
   : public Domain< Operator::getMeshDimensions(), 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,10 +255,10 @@ 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 Function PreimageFunctionType;
       typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > 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(); };
@@ -286,7 +287,7 @@ 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;
       }
@@ -357,6 +358,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::getDomainDimensions(), Function::getDomainType() >
+{
+   public:
+      
+      typedef Function FunctionType;
+      typedef typename FunctionType::RealType RealType;
+      typedef typename FunctionType::VertexType VertexType;
+      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 VertexType& 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..d1b78ffb89ce6ba324d455fb3292dc1c214ffdf1 100644
--- a/src/TNL/Functions/TestFunction.h
+++ b/src/TNL/Functions/TestFunction.h
@@ -26,109 +26,129 @@ class TestFunction : public Domain< FunctionDimensions, 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{ Dimensions = FunctionDimensions };
+      typedef Real RealType;
+      typedef Containers::StaticVector< Dimensions, Real > VertexType;
+
+      TestFunction();
+
+      static void configSetup( Config::ConfigDescription& config,
+                               const String& prefix = "" );
+
+      bool setup( const Config::ParameterContainer& parameters,
+                 const String& prefix = "" );
+
+      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,
+                                 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;
 
-   TestFunction();
+   #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
 
-   static void configSetup( Config::ConfigDescription& config,
-                            const String& prefix = "" );
+      std::ostream& print( std::ostream& str ) const;
 
-   bool setup( const Config::ParameterContainer& parameters,
-              const String& prefix = "" );
+      ~TestFunction();
 
-   const TestFunction& operator = ( const TestFunction& function );
+   protected:
 
-#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,
-                              const Real& time = 0 ) const;
+      template< typename FunctionType >
+      bool setupFunction( const Config::ParameterContainer& parameters,
+                         const String& prefix = "" );
+      
+      template< typename OperatorType >
+      bool setupOperator( const Config::ParameterContainer& parameters,
+                          const String& prefix = "" );
 
-   __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();
 
-   protected:
+      template< typename FunctionType >
+      void deleteFunction();
 
-   template< typename FunctionType >
-   bool setupFunction( const Config::ParameterContainer& parameters,
-                      const String& prefix = "" );
+      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;
 
 };
 
diff --git a/src/TNL/Functions/TestFunction_impl.h b/src/TNL/Functions/TestFunction_impl.h
index 506f536518d1946e33da00f749097b168bd8d09d..a7bfdf513f3e9a088dff1354c26f26d77129dbda 100644
--- a/src/TNL/Functions/TestFunction_impl.h
+++ b/src/TNL/Functions/TestFunction_impl.h
@@ -24,16 +24,29 @@
 #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,
           typename Real,
           typename Device >
 TestFunction< FunctionDimensions, Real, Device >::
 TestFunction()
 : function( 0 ),
+  operator_( 0 ),
   timeDependence( none ),
   timeScale( 1.0 )
 {
@@ -49,6 +62,7 @@ configSetup( Config::ConfigDescription& config,
 {
    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 +71,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 +91,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" );
@@ -113,6 +138,36 @@ setupFunction( const Config::ParameterContainer& parameters,
    return true;
 }
 
+template< int FunctionDimensions,
+          typename Real,
+          typename Device >
+   template< typename OperatorType >
+bool
+TestFunction< FunctionDimensions, 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( ! checkCudaDevice )
+         return false;
+   }
+   return true;
+}
+
 template< int FunctionDimensions,
           typename Real,
           typename Device >
@@ -122,6 +177,7 @@ 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,60 +196,141 @@ 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 Identity< Dimensions, Real > OperatorType;
       functionType = constant;
-      return setupFunction< FunctionType >( parameters );
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
+   if( testFunction == "paraboloid" )
+   {
+      typedef Paraboloid< Dimensions, Real > FunctionType;
+      typedef Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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 Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+      typedef Identity< Dimensions, Real > OperatorType;
+      functionType = paraboloidSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }   
+   if( testFunction == "sin-bumps-sdf" )
+   {
+      typedef SinBumpsSDF< Dimensions, Real > FunctionType;
+      typedef Identity< Dimensions, Real > OperatorType;
+      functionType = sinBumpsSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }   
+   if( testFunction == "sin-wave-sdf" )
+   {
+      typedef SinWaveSDF< Dimensions, Real > FunctionType;
+      typedef Identity< Dimensions, Real > OperatorType;
+      functionType = sinWaveSDF;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }
+   if( testFunction == "vector-norm" )
+   {
+      typedef VectorNorm< Dimensions, Real > FunctionType;
+      typedef Identity< Dimensions, Real > OperatorType;
+      functionType = vectorNorm;
+      operatorType = identity;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
+   }
+   if( testFunction == "heaviside-of-vector-norm" )
+   {
+      typedef VectorNorm< Dimensions, Real > FunctionType;
+      typedef Heaviside< Dimensions, Real > OperatorType;
+      functionType = vectorNorm;
+      operatorType = heaviside;
+      return ( setupFunction< FunctionType >( parameters, prefix ) && 
+               setupOperator< OperatorType >( parameters, prefix ) );
    }
    std::cerr << "Unknown function " << testFunction << std::endl;
    return false;
@@ -246,11 +383,20 @@ operator = ( const TestFunction& function )
       case blob:
          this->copyFunction< Blob< FunctionDimensions, Real > >( function.function );
          break;
+
+      case paraboloidSDF:
+         this->copyFunction< Paraboloid< FunctionDimensions, Real > >( function.function );
+         break;
+      case sinBumpsSDF:
+         this->copyFunction< SinBumpsSDF< FunctionDimensions, Real > >( function.function );
+         break;
+      case sinWaveSDF:
+         this->copyFunction< SinWaveSDF< FunctionDimensions, Real > >( function.function );
+         break;
       default:
          TNL_ASSERT( false, );
          break;
    }
-
 }
 
 template< int FunctionDimensions,
@@ -263,9 +409,10 @@ __cuda_callable__
 Real
 TestFunction< FunctionDimensions, Real, Device >::
 getPartialDerivative( const VertexType& vertex,
-          const Real& time ) const
+                      const Real& time ) const
 {
    using namespace TNL::Functions::Analytic;
+   using namespace TNL::Operators::Analytic;
    Real scale( 1.0 );
    switch( this->timeDependence )
    {
@@ -286,32 +433,138 @@ getPartialDerivative( const VertexType& vertex,
    switch( functionType )
    {
       case constant:
-         return scale * ( ( Constant< Dimensions, Real >* ) function )->
-                   template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      {
+         typedef Constant< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, Real > OperatorType;
+
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimensions, Real > FunctionType;
+         if( operatorType == identity )
+         {
+            typedef Identity< Dimensions, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+         if( operatorType == heaviside )
+         {
+            typedef Heaviside< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, 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< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case vectorNorm:
+      {
+         typedef VectorNorm< Dimensions, Real > FunctionType;
+         if( operatorType == identity )
+         {
+            typedef Identity< Dimensions, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+         if( operatorType == heaviside )
+         {
+            typedef Heaviside< Dimensions, Real > OperatorType;
+
+            return scale * ( ( OperatorType* ) this->operator_ )->
+                      template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+         }
+      }      
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, Real > OperatorType;
+                  
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimensions, Real > FunctionType;
+         typedef Identity< Dimensions, Real > OperatorType;
+         
+         return scale * ( ( OperatorType* ) this->operator_ )->
+                   template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time );
+      }
+      
       default:
          return 0.0;
    }
@@ -348,38 +601,91 @@ getTimeDerivative( const VertexType& vertex,
    switch( functionType )
    {
       case constant:
-         return scale * ( ( Constant< Dimensions, Real >* ) function )->
+      {
+         typedef Constant< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case expBump:
-         return scale * ( ( ExpBump< Dimensions, Real >* ) function )->
+      {
+         typedef ExpBump< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case sinBumps:
-         return scale * ( ( SinBumps< Dimensions, Real >* ) function )->
+      {
+         typedef SinBumps< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       case sinWave:
-         return scale * ( ( SinWave< Dimensions, Real >* ) function )->
+      {
+         typedef SinWave< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case cylinder:
-         return scale * ( ( Cylinder< Dimensions, Real >* ) function )->
+      {
+         typedef Cylinder< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case flowerpot:
-         return scale * ( ( Flowerpot< Dimensions, Real >* ) function )->
+      {
+         typedef Flowerpot< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case twins:
-         return scale * ( ( Twins< Dimensions, Real >* ) function )->
+      {
+         typedef Twins< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case pseudoSquare:
-         return scale * ( ( PseudoSquare< Dimensions, Real >* ) function )->
+      {
+         typedef PseudoSquare< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
       case blob:
-         return scale * ( ( Blob< Dimensions, Real >* ) function )->
+      {
+         typedef Blob< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
+      }
+
+
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimensions, Real > FunctionType;
+         return scale * ( ( FunctionType* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
       default:
          return 0.0;
    }
@@ -405,6 +711,26 @@ deleteFunction()
    }
 }
 
+template< int FunctionDimensions,
+          typename Real,
+          typename Device >
+   template< typename OperatorType >
+void
+TestFunction< FunctionDimensions, 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 FunctionDimensions,
           typename Real,
           typename Device >
@@ -413,35 +739,112 @@ TestFunction< FunctionDimensions, Real, Device >::
 deleteFunctions()
 {
    using namespace TNL::Functions::Analytic;
+   using namespace TNL::Operators::Analytic;
    switch( functionType )
    {
       case constant:
-         deleteFunction< Constant< Dimensions, Real> >();
-         break;
+      {
+         typedef Constant< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
+      case paraboloid:
+      {
+         typedef Paraboloid< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         if( operatorType == identity )
+            deleteOperator< Identity< Dimensions, Real > >();
+         if( operatorType == heaviside )
+            deleteOperator< Heaviside< Dimensions, Real > >();
+         break;
+      }
       case expBump:
-         deleteFunction< ExpBump< Dimensions, Real> >();
+      {
+         typedef ExpBump< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case sinBumps:
-         deleteFunction< SinBumps< Dimensions, Real> >();
+      {
+         typedef SinBumps< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case sinWave:
-         deleteFunction< SinWave< Dimensions, Real> >();
+      {
+         typedef SinWave< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case cylinder:
-         deleteFunction< Cylinder< Dimensions, Real> >();
+      {
+         typedef Cylinder< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case flowerpot:
-         deleteFunction< Flowerpot< Dimensions, Real> >();
+      {
+         typedef Flowerpot< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case twins:
-         deleteFunction< Twins< Dimensions, Real> >();
+      {
+         typedef Twins< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case pseudoSquare:
-         deleteFunction< PseudoSquare< Dimensions, Real> >();
+      {
+         typedef PseudoSquare< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
          break;
+      }
       case blob:
-         deleteFunction< Blob< Dimensions, Real> >();
-         break;
+      {
+         typedef Blob< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
+      case vectorNorm:
+      {
+         typedef VectorNorm< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
+      
+      
+      case paraboloidSDF:
+      {
+         typedef ParaboloidSDF< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
+      case sinBumpsSDF:
+      {
+         typedef SinBumpsSDF< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
+      case sinWaveSDF:
+      {
+         typedef SinWaveSDF< Dimensions, Real> FunctionType;
+         deleteFunction< FunctionType >();
+         deleteOperator< Identity< Dimensions, Real > >();
+         break;
+      }
    }
 }
 
@@ -484,7 +887,6 @@ printFunction( std::ostream& str ) const
       Devices::Cuda::print( f, str );
       return str;
    }
-   return str;
 }
 
 template< int FunctionDimensions,
diff --git a/src/TNL/Functions/VectorField.h b/src/TNL/Functions/VectorField.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f98b65fcc1370166c38e49760fb7836eeecfd7c
--- /dev/null
+++ b/src/TNL/Functions/VectorField.h
@@ -0,0 +1,278 @@
+/***************************************************************************
+                          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::getDomainDimensions(), 
+                               Function::getDomainType() >
+{
+   public:
+      
+      typedef Function FunctionType;
+      typedef typename FunctionType::RealType RealType;
+      typedef typename FunctionType::VertexType VertexType;
+      
+      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 MeshEntityDimensions,
+          typename Real >
+class VectorField< Size, MeshFunction< Mesh, MeshEntityDimensions, Real > >
+: public Functions::Domain< MeshFunction< Mesh, MeshEntityDimensions, Real >::getDomainDimensions(), 
+                            MeshFunction< Mesh, MeshEntityDimensions, Real >::getDomainType() >,
+   public Object
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef SharedPointer< MeshType > MeshPointer;
+      typedef MeshFunction< MeshType, MeshEntityDimensions, RealType > FunctionType;
+      typedef SharedPointer< FunctionType > FunctionPointer;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef VectorField< Size, MeshFunction< Mesh, MeshEntityDimensions, 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++ )
+            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++ )
+            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 Dimensions,
+          typename Function >
+std::ostream& operator << ( std::ostream& str, const VectorField< Dimensions, Function >& f )
+{
+   for( int i = 0; i < Dimensions; i++ )
+   {
+      str << "[ " << f[ i ] << " ]";
+      if( i < Dimensions - 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..6ec84a722e7897fb0d58cc226628c208000dc86e
--- /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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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::VertexType 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/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/Math.h b/src/TNL/Math.h
index 62ff2bb95e7aaac0b7e9686ef43019f58cff9ae0..1ff7cc923c8eed40b6676bed16e8371137b88c04 100644
--- a/src/TNL/Math.h
+++ b/src/TNL/Math.h
@@ -182,9 +182,9 @@ 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 >
diff --git a/src/TNL/Matrices/Dense_impl.h b/src/TNL/Matrices/Dense_impl.h
index 783e3b6035a8120c2525da5a9832dd86ecef28ae..bec9ec70df66818844d2ceea852cd8c1d304958f 100644
--- a/src/TNL/Matrices/Dense_impl.h
+++ b/src/TNL/Matrices/Dense_impl.h
@@ -153,8 +153,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,9 +166,9 @@ 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 )
 {
    TNL_ASSERT( row >= 0 && row < this->getRows() &&
               column >= 0 && column < this->getColumns(),
diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h
index d2a96c4ad5bae4bf19374c90a60cfbd5d146b100..514e964a94f6e569b8757d0c72aa14a99e0b374f 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D.h
@@ -63,30 +63,35 @@ 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 );
 
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   const VertexType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
- 
+   const VertexType& getProportions() const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline IndexType getEntitiesCount() const;
- 
+   IndexType getEntitiesCount() const;
+   
+   template< int EntiytDimensions >
+   __cuda_callable__
+   IndexType getEntitiesCount() const;
+   
+   
    template< typename EntityType >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
- 
+   EntityType getEntity( const IndexType& entityIndex ) const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
- 
+   Index getEntityIndex( const EntityType& entity ) const;
+   
    template< typename EntityType >
    __cuda_callable__
    RealType getEntityMeasure( const EntityType& entity ) const;
@@ -95,14 +100,14 @@ class Grid< 1, Real, Device, Index > : public Object
    inline const RealType& getCellMeasure() const;
  
    __cuda_callable__
-   inline const VertexType& getSpaceSteps() const;
+   const VertexType& getSpaceSteps() const { return this->spaceSteps;}
 
    template< int xPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
- 
+   const RealType& getSpaceStepsProducts() const;
+   
    __cuda_callable__
-   inline RealType getSmallestSpaceStep() const;
+   RealType getSmallestSpaceStep() const;
 
 
    template< typename GridFunction >
diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
index cac0ad3da8884483d4f48e91b62baba5b30b0dda..fc82381ebb27dffe37df27dd30caec473c8ffa56 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
@@ -168,6 +168,29 @@ getEntitiesCount() const
    return -1;
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< int EntityDimensions >
+__cuda_callable__  inline
+Index
+Grid< 1, Real, Device, Index >::
+getEntitiesCount() const
+{
+   static_assert( EntityDimensions <= 1 &&
+                  EntityDimensions >= 0, "Wrong grid entity dimensions." );
+ 
+   switch( EntityDimensions )
+   {
+      case 1:
+         return this->numberOfCells;
+      case 0:
+         return this->numberOfVertices;
+   }
+   return -1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -221,16 +244,16 @@ getCellMeasure() const
    return this->template getSpaceStepsProducts< 1 >();
 }
 
-template< typename Real,
+/*template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__ inline
-const typename Grid< 1, Real, Device, Index >::VertexType&
+__cuda_callable__
+typename Grid< 1, Real, Device, Index >::VertexType
 Grid< 1, Real, Device, Index >::
 getSpaceSteps() const
 {
    return this->spaceSteps;
-}
+}*/
 
 template< typename Real,
           typename Device,
diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h
index 6c7dfca7f61089f61c8ec2d9e5d4be995f3c9906..1a403508f7d0b69d5ec4620436df2769b63c7096 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D.h
@@ -69,27 +69,32 @@ 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 );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   const VertexType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   const VertexType& getProportions() const;
 
+
+   template< int EntityDimensions >
+   __cuda_callable__
+   IndexType getEntitiesCount() const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline IndexType getEntitiesCount() const;
- 
+   IndexType getEntitiesCount() const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
- 
+   EntityType getEntity( const IndexType& entityIndex ) const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
+   Index getEntityIndex( const EntityType& entity ) const;
 
    template< typename EntityType >
    __cuda_callable__
@@ -99,14 +104,14 @@ class Grid< 2, Real, Device, Index > : public Object
    inline const RealType& getCellMeasure() const;
  
    __cuda_callable__
-   inline const VertexType& getSpaceSteps() const;
+   const VertexType& getSpaceSteps() const { return this->spaceSteps; }
 
    template< int xPow, int yPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
- 
+   const RealType& getSpaceStepsProducts() const;
+   
    __cuda_callable__
-   inline RealType getSmallestSpaceStep() const;
+   RealType getSmallestSpaceStep() const;
 
  
    template< typename GridFunction >
diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
index 4d0d87fb2f1d7f752c6330c94c90137b7cb3830d..f0aa205d420be259ce63cfae6a98dcd9644d25c1 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
@@ -196,6 +196,31 @@ const typename Grid< 2, Real, Device, Index > :: VertexType&
    return this->proportions;
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< int EntityDimensions >
+__cuda_callable__ inline
+Index
+Grid< 2, Real, Device, Index >::
+getEntitiesCount() const
+{
+   static_assert( EntityDimensions <= 2 &&
+                  EntityDimensions >= 0, "Wrong grid entity dimensions." );
+ 
+   switch( EntityDimensions )
+   {
+      case 2:
+         return this->numberOfCells;
+      case 1:
+         return this->numberOfFaces;
+      case 0:
+         return this->numberOfVertices;
+   }
+   return -1;
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -274,16 +299,16 @@ getCellMeasure() const
 }
 
 
-template< typename Real,
+/*template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__ inline
-const typename Grid< 2, Real, Device, Index >::VertexType&
+__cuda_callable__
+typename Grid< 2, Real, Device, Index >::VertexType&
 Grid< 2, Real, Device, Index >::
 getSpaceSteps() const
 {
    return this->spaceSteps;
-}
+}*/
 
 template< typename Real,
           typename Device,
diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h
index 860b5e473528cf0de601648a77bb0bd6f0aba490..fd1e91ac0e1298b05f917a1df383db989437b11f 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D.h
@@ -62,28 +62,32 @@ 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 );
    __cuda_callable__
-   inline const VertexType& getOrigin() const;
+   const VertexType& getOrigin() const;
 
    __cuda_callable__
-   inline const VertexType& getProportions() const;
+   const VertexType& getProportions() const;
 
    template< typename EntityType >
    __cuda_callable__
-   inline IndexType getEntitiesCount() const;
- 
+   IndexType getEntitiesCount() const;
+   
+   template< int Dimensions >
+   __cuda_callable__
+   IndexType getEntitiesCount() const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline EntityType getEntity( const IndexType& entityIndex ) const;
- 
+   EntityType getEntity( const IndexType& entityIndex ) const;
+   
    template< typename EntityType >
    __cuda_callable__
-   inline Index getEntityIndex( const EntityType& entity ) const;
- 
+   Index getEntityIndex( const EntityType& entity ) const;
+   
    template< typename EntityType >
    __cuda_callable__
    RealType getEntityMeasure( const EntityType& entity ) const;
@@ -92,16 +96,16 @@ class Grid< 3, Real, Device, Index > : public Object
    inline const RealType& getCellMeasure() const;
 
    __cuda_callable__
-   inline const VertexType& getSpaceSteps() const;
- 
+   const VertexType& getSpaceSteps() const { return this->spaceSteps; };
+   
    template< int xPow, int yPow, int zPow >
    __cuda_callable__
-   inline const RealType& getSpaceStepsProducts() const;
+   const RealType& getSpaceStepsProducts() const;
 
  
    __cuda_callable__
-   inline RealType getSmallestSpaceStep() const;
- 
+   RealType getSmallestSpaceStep() const;
+      
    template< typename GridFunction >
    typename GridFunction::RealType getAbsMax( const GridFunction& f ) const;
 
diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
index d9cdaa1dfe62359328f11c369cd16d0a43d168d5..9282d1500e1ccb18d58810654dfdbc989304e73c 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
@@ -268,6 +268,32 @@ getEntitiesCount() const
    return -1;
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< int EntityDimensions >
+__cuda_callable__  inline
+Index
+Grid< 3, Real, Device, Index >::
+getEntitiesCount() const
+{
+   static_assert( EntityDimensions <= 3 &&
+                  EntityDimensions >= 0, "Wrong grid entity dimensions." );
+ 
+   switch( EntityDimensions )
+   {
+      case 3:
+         return this->numberOfCells;
+      case 2:
+         return this->numberOfFaces;
+      case 1:
+         return this->numberOfEdges;
+      case 0:
+         return this->numberOfVertices;
+   }
+   return -1;
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -321,16 +347,16 @@ getCellMeasure() const
    return this->template getSpaceStepsProducts< 1, 1, 1 >();
 }
 
-template< typename Real,
+/*template< typename Real,
           typename Device,
           typename Index >
-__cuda_callable__ inline
-const typename Grid< 3, Real, Device, Index >::VertexType&
+__cuda_callable__
+typename Grid< 3, Real, Device, Index >::VertexType&
 Grid< 3, Real, Device, Index >::
 getSpaceSteps() const
 {
    return this->spaceSteps;
-}
+}*/
 
 template< typename Real,
           typename Device,
diff --git a/src/TNL/Operators/Advection/CMakeLists.txt b/src/TNL/Operators/Advection/CMakeLists.txt
new file mode 100755
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..9b939e184cee92bfbdef1edff999b15cdf539aee
--- /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::getMeshDimensions();
+      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::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 >(); 
+         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::getMeshDimensions();
+      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::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 >(); 
+         
+         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::getMeshDimensions();
+      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::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 >(); 
+         
+         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 100755
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..4449998015aee2936bc7599843e3c40ed3f29d2b
--- /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 > VertexType;
+      
+      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 VertexType& 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 VertexType& 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..fdc4824480735c3fe7e780966628340202370d72
--- /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 > VertexType;
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" )
+      {
+         return true;
+      };
+      
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const VertexType& 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 VertexType& vertex,
+                                     const RealType& time = 0 ) const
+      {
+         return function.getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      }
+      
+};
+
+} // namespace Analytic
+} // namespace Operators
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Operators/Analytic/Rotation.h b/src/TNL/Operators/Analytic/Rotation.h
new file mode 100644
index 0000000000000000000000000000000000000000..272e9ae85ca877e6bfa0caf551e055fb8aef5ae4
--- /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 > VertexType;
+      
+      RotationBase() : center( 0.0 ) {};
+      
+      void setCenter( const VertexType& center )
+      {
+         this->center = center;
+      }
+      
+      __cuda_callable__
+      const VertexType& getCenter() const
+      {
+         return this->center;
+      }
+      
+   protected:
+      
+      VertexType 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 > VertexType;
+      
+      bool setup( const Config::ParameterContainer& parameters,
+                  const String& prefix = "" ){};
+      
+      
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const VertexType& 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..d5e8580ccf338972ed196d32f911d3655477d67f
--- /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 > VertexType;
+      
+      
+      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 VertexType& shift )
+      {
+         this->shift = shift;
+      }
+      
+      __cuda_callable__
+      const VertexType& getShift() const
+      {
+         return this->shift;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      RealType operator()( const Function& function,
+                           const VertexType& 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 VertexType& 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:
+      
+      VertexType 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..ea18af636270b28372c5196c0a85f88e95b6c445
--- /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 > VertexType;
+      
+      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 VertexType& 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 VertexType& 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..e3f13c4d7fe8c3db79605f4556ff21106e4ca619
--- /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 > VertexType;
+      
+      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 VertexType& 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 VertexType& 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
index dcdb7d3ddaae05cffedbe0d9468002b63ca41328..63385c2a49e16c771f1c7970180ddd97ac3be5f4 100755
--- 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/NeumannBoundaryConditions.h b/src/TNL/Operators/NeumannBoundaryConditions.h
index 1461135eebaa135043e1f60452a178f2633b4737..f39eb64744df7ecf29823ca79e92bdb494711d53 100644
--- a/src/TNL/Operators/NeumannBoundaryConditions.h
+++ b/src/TNL/Operators/NeumannBoundaryConditions.h
@@ -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()
       {
@@ -112,7 +124,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
       const auto& neighbourEntities = entity.getNeighbourEntities();
       const IndexType& index = entity.getIndex();
       if( entity.getCoordinates().x() == 0 )
-         return u[ neighbourEntities.template getEntityIndex< 1 >() ] - entity.getMesh().getSpaceSteps().x() * 
+         return u[ neighbourEntities.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() * 
@@ -149,7 +161,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index, 1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().x() * 
+            b[ index ] = entity.getMesh().getSpaceSteps().x() * 
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          else
@@ -207,7 +219,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
          const IndexType& index = entity.getIndex();
          if( entity.getCoordinates().x() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+            return u[ neighbourEntities.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 )
@@ -217,7 +229,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
          }
          if( entity.getCoordinates().y() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - entity.getMesh().getSpaceSteps().y() *
+            return u[ neighbourEntities.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
@@ -256,7 +268,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index,                                                1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().x() *
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
@@ -270,7 +282,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index,                                                1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().y() *
+            b[ index ] = entity.getMesh().getSpaceSteps().y() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
@@ -326,7 +338,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          const IndexType& index = entity.getIndex();
          if( entity.getCoordinates().x() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+            return u[ neighbourEntities.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 )
@@ -336,7 +348,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          }
          if( entity.getCoordinates().y() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - entity.getMesh().getSpaceSteps().y() *
+            return u[ neighbourEntities.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 )
@@ -346,7 +358,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          }
          if( entity.getCoordinates().z() == 0 )
          {
-            return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - entity.getMesh().getSpaceSteps().z() *
+            return u[ neighbourEntities.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
@@ -386,7 +398,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index,                                                   1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().x() *
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
@@ -400,7 +412,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index,                                                   1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().y() * 
+            b[ index ] = entity.getMesh().getSpaceSteps().y() * 
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
@@ -414,7 +426,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >,
          {
             matrixRow.setElement( 0, index,                                                   1.0 );
             matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 );
-            b[ index ] = - entity.getMesh().getSpaceSteps().z() *
+            b[ index ] = entity.getMesh().getSpaceSteps().z() *
                Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
          }
          if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 )
@@ -440,4 +452,3 @@ std::ostream& operator << ( std::ostream& str, const NeumannBoundaryConditions<
 } // namespace Operators
 } // namespace TNL
 
-
diff --git a/src/TNL/Problems/HeatEquationProblem.h b/src/TNL/Problems/HeatEquationProblem.h
index 33046f58cc847a3654057da2150504ef77447de5..59d57ff2f56e7c55ee1d09eff951cf92ee36a9ae 100644
--- a/src/TNL/Problems/HeatEquationProblem.h
+++ b/src/TNL/Problems/HeatEquationProblem.h
@@ -32,9 +32,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:
 
diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h
index 6dc77992669e167ca200a820a87bf32be79d4178..e4e8818a99004a6168dbd367acb45c6c1cbd3a64 100644
--- a/src/TNL/Problems/HeatEquationProblem_impl.h
+++ b/src/TNL/Problems/HeatEquationProblem_impl.h
@@ -183,10 +183,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" );
diff --git a/src/TNL/Solvers/IterativeSolver_impl.h b/src/TNL/Solvers/IterativeSolver_impl.h
index 5f8c084d799c88a33f7a00c51532c9d233b810cf..da811762ae2b5d1f11f5748e37d52b4026a7f78e 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;
 }
 
diff --git a/src/TNL/Solvers/ODE/Euler_impl.h b/src/TNL/Solvers/ODE/Euler_impl.h
index 46706cf24c8796ed6e92681cadbfed46fddad102..6571dee4d0d2ccf3c097a0ec358e22118d64c0a5 100644
--- a/src/TNL/Solvers/ODE/Euler_impl.h
+++ b/src/TNL/Solvers/ODE/Euler_impl.h
@@ -27,8 +27,6 @@ template< typename Problem >
 Euler< Problem > :: Euler()
 : cflCondition( 0.0 )
 {
-   //timer.reset();
-   //updateTimer.reset();
 };
 
 template< typename Problem >
@@ -60,13 +58,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 >
@@ -94,7 +92,7 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
    this->resetIterations();
    this->setResidue( this->getConvergenceResidue() + 1.0 );
 
-   this->refreshSolverMonitor();
+   this -> refreshSolverMonitor();
 
    /****
     * Start the main loop
@@ -104,13 +102,11 @@ bool Euler< Problem > :: solve( DofVectorPointer& u )
       /****
        * Compute the RHS
        */
-      //timer.stop();
       this->problem->getExplicitRHS( 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() );
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..11cd7f19285e21d92ddeeb4bcff98897ab59f0d9 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,7 @@ refreshSolverMonitor()
       this->solverMonitor->setTimeStep( this->getTau() );
       this->solverMonitor->setTime( this->getTime() );
       this->solverMonitor->setRefreshRate( this->refreshRate );
-      this->solverMonitor->refresh();
+      this->solverMonitor->refresh( force );
    }
 }
 
diff --git a/src/TNL/Solvers/ODE/Merson_impl.h b/src/TNL/Solvers/ODE/Merson_impl.h
index 868bc32b59ce652acd55c7f1c58c39a172478e45..13afdb4df56fb94438272c4fb4e8f94750b68b57 100644
--- a/src/TNL/Solvers/ODE/Merson_impl.h
+++ b/src/TNL/Solvers/ODE/Merson_impl.h
@@ -170,7 +170,7 @@ bool Merson< Problem > :: solve( DofVectorPointer& u )
    /****
     * Start the main loop
     */
-   while( 1 )
+   while( this->checkNextIteration() )
    {
       /****
        * Compute Runge-Kutta coefficients
@@ -227,10 +227,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 >
diff --git a/src/TNL/Solvers/PDE/CMakeLists.txt b/src/TNL/Solvers/PDE/CMakeLists.txt
index 0f98d12a9f92b80279e810041ec9e4ba42f7bfaa..e01c13e93a3228e51c01915ad133077987112969 100755
--- a/src/TNL/Solvers/PDE/CMakeLists.txt
+++ b/src/TNL/Solvers/PDE/CMakeLists.txt
@@ -7,8 +7,10 @@ SET( headers BackwardTimeDiscretisation.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/PDESolver.h b/src/TNL/Solvers/PDE/TimeDependentPDESolver.h
similarity index 93%
rename from src/TNL/Solvers/PDE/PDESolver.h
rename to src/TNL/Solvers/PDE/TimeDependentPDESolver.h
index a4f47ef51c8e6472c8d4807254c98db8cdc5f661..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 = "" );
@@ -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 86%
rename from src/TNL/Solvers/PDE/PDESolver_impl.h
rename to src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h
index 139d8fcc95169bd2938eb2ba9397b51425b962d4..2a22201d1e54f2d75b809c5b2e914abb332bd390 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 )
 {
@@ -121,7 +121,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 )
 {
@@ -172,7 +172,7 @@ writeProlog( Logger& logger,
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setTimeStepper( TimeStepper& timeStepper )
 {
    this->timeStepper = &timeStepper;
@@ -181,7 +181,7 @@ setTimeStepper( TimeStepper& timeStepper )
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setProblem( ProblemType& problem )
 {
    this->problem = &problem;
@@ -190,7 +190,7 @@ setProblem( ProblemType& problem )
 template< typename Problem,
           typename TimeStepper >
 void
-PDESolver< Problem, TimeStepper >::
+TimeDependentPDESolver< Problem, TimeStepper >::
 setInitialTime( const RealType& initialTime )
 {
    this->initialTime = initialTime;
@@ -199,7 +199,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;
@@ -209,12 +209,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;
@@ -224,7 +224,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;
@@ -233,12 +233,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;
@@ -248,7 +248,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;
@@ -257,12 +257,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;
@@ -272,7 +272,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;
@@ -281,12 +281,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;
@@ -296,27 +296,27 @@ 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()
 {
    TNL_ASSERT( timeStepper != 0,
@@ -326,7 +326,7 @@ solve()
 
    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 );
@@ -376,7 +376,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..0f27de6489ffc3ee7a4ec37d6ca1d69c766f913a
--- /dev/null
+++ b/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h
@@ -0,0 +1,172 @@
+/***************************************************************************
+                          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( problem->getDofs( this->mesh ) != 0, );
+   cout << "Allocating dofs ... ";
+   if( ! this->dofs.setSize( problem->getDofs( this->mesh ) ) )
+   {
+      cerr << endl;
+      cerr << "I am not able to allocate DOFs (degrees of freedom)." << endl;
+      return false;
+   }
+   cout << " [ OK ]" << endl;
+   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( problem != 0,
+              cerr << "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/SolverConfig_impl.h b/src/TNL/Solvers/SolverConfig_impl.h
index eb981bb35b9ade583e8538376978443e04584e14..a191add046b7f1b4e2b317a26e4abd23ee96606d 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 {
@@ -79,7 +79,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 ||
diff --git a/src/TNL/Solvers/SolverStarter_impl.h b/src/TNL/Solvers/SolverStarter_impl.h
index 2d988c8b4120920ca346dd7e8e205b43f64660f9..516dab97d42bf11b0aa4185bc1acf01db2ab1542 100644
--- a/src/TNL/Solvers/SolverStarter_impl.h
+++ b/src/TNL/Solvers/SolverStarter_impl.h
@@ -27,7 +27,7 @@
 #include <TNL/Solvers/Linear/Preconditioners/Diagonal.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 {   
@@ -358,7 +358,7 @@ bool SolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
    /****
     * Set-up the PDE solver
     */
-   PDE::PDESolver< Problem, TimeStepper > solver;
+   PDE::TimeDependentPDESolver< Problem, TimeStepper > solver;
    solver.setProblem( problem );
    solver.setTimeStepper( timeStepper );
    if( ! solver.setup( parameters ) )
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-diff.h b/src/Tools/tnl-diff.h
index 73036199d0dcb70c3d32ad1fcfae7d1f4e68318e..d8ee5077cc1f0e3d3eb7e239d75e710463f81933 100644
--- a/src/Tools/tnl-diff.h
+++ b/src/Tools/tnl-diff.h
@@ -416,7 +416,7 @@ bool setElementType( const MeshPointer& meshPointer,
       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;
diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h
index 60c366c4aa581f4cb107d12b1357aef61e966440..4f0456aea2dc44edd4eb0f94b8237ea5dd8dfbe8 100644
--- a/src/Tools/tnl-view.h
+++ b/src/Tools/tnl-view.h
@@ -19,6 +19,7 @@
 #include <TNL/Containers/MultiVector.h>
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Functions/MeshFunction.h>
+#include <TNL/Functions/VectorField.h>
 
 using namespace TNL;
 
@@ -48,6 +49,7 @@ 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 ) )
@@ -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,38 +69,73 @@ 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 >
+          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, EntityDimensions, Real > >( meshPointer, inputFileName, parameters );
+   return writeVectorField< Functions::VectorField< VectorFieldSize, Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimensions, Real > > >( meshPointer, inputFileName, parameters );
 }
 
 template< typename MeshPointer,
-          int EntityDimensions >
+          int EntityDimensions,
+          int VectorFieldSize >
 bool setMeshEntityType( const MeshPointer& meshPointer,
                         const String& inputFileName,
                         const Containers::List< String >& parsedObjectType,
                         const Config::ParameterContainer& parameters )
 {
    if( parsedObjectType[ 3 ] == "float" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, float >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimensions, float, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( parsedObjectType[ 3 ] == "double" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, double >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimensions, double, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters );
    if( parsedObjectType[ 3 ] == "long double" )
-      return setMeshFunctionRealType< MeshPointer, EntityDimensions, long double >( meshPointer, inputFileName, parameters );
+      return setMeshFunctionRealType< MeshPointer, EntityDimensions, 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 >
+          typename MeshIndex,
+          int VectorFieldSize >
 bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
                               const Containers::List< String >& parsedObjectType,
@@ -109,10 +147,10 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, De
    switch( meshEntityDimensions )
    {
       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;
@@ -121,7 +159,8 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, De
 }
 
 template< typename MeshReal,
-          typename MeshIndex >
+          typename MeshIndex,
+          int VectorFieldSize >
 bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
                               const Containers::List< String >& parsedObjectType,
@@ -133,13 +172,13 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, De
    switch( meshEntityDimensions )
    {
       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;
@@ -148,7 +187,8 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, De
 }
 
 template< typename MeshReal,
-          typename MeshIndex >
+          typename MeshIndex,
+          int VectorFieldSize >
 bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, Devices::Host, MeshIndex > >& meshPointer,
                               const String& inputFileName,
                               const Containers::List< String >& parsedObjectType,
@@ -160,16 +200,16 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, De
    switch( meshEntityDimensions )
    {
       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;
@@ -177,20 +217,48 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, De
    }
 }
 
-template< typename MeshPointer >
+template< typename MeshPointer, int VectorFieldSize = 0 >
 bool setMeshFunction( const MeshPointer& meshPointer,
                       const String& inputFileName,
                       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 setMeshEntityDimensions< 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 >
 bool convertObject( const MeshPointer& meshPointer,
@@ -380,7 +448,7 @@ bool setElementType( const MeshPointer& meshPointer,
       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;
@@ -456,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/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp
index 1063d139dc9781af1fafc2f8ecf34e2a6c8401fe..3a0444ed64801402a95cec5a2ba80aa739e05163 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
diff --git a/src/core/tnlTypeInfo.h b/src/core/tnlTypeInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d5282f3c4ed13bcc190446f7c1026ac28663944
--- /dev/null
+++ b/src/core/tnlTypeInfo.h
@@ -0,0 +1,39 @@
+/* 
+ * File:   tnlTypeInfo.h
+ * Author: oberhuber
+ *
+ * Created on July 14, 2016, 3:46 PM
+ */
+
+#pragma once
+
+#include <limits>
+
+template< typename Type >
+class tnlTypeInfo
+{   
+};
+
+template<>
+class tnlTypeInfo< double >
+{
+   public:
+      
+      typedef double Type;
+      
+      static __cuda_callable__
+      Type getMaxValue() { return DBL_MAX; };
+};
+
+template<>
+class tnlTypeInfo< float >
+{
+   public:
+      
+      typedef float Type;
+      
+      static __cuda_callable__
+      Type getMaxValue() { return FLT_MAX; };
+};
+
+
diff --git a/src/functions/tnlFunctions.h b/src/functions/tnlFunctions.h
new file mode 100644
index 0000000000000000000000000000000000000000..326fa6024b37256360fb6653d195310fe6eb9a98
--- /dev/null
+++ b/src/functions/tnlFunctions.h
@@ -0,0 +1,52 @@
+/* 
+ * File:   tnlFunctions.h
+ * Author: oberhuber
+ *
+ * Created on July 11, 2016, 6:01 PM
+ */
+
+#pragma once
+
+#include <core/tnlCuda.h>
+
+template< typename Real >
+__cuda_callable__
+Real sign( const Real& x, const Real& smoothing = 0.0 )
+{
+   if( x > smoothing )
+      return 1.0;
+   else if( x < -smoothing )
+      return -1.0;
+   if( smoothing == 0.0 )
+      return 0.0;
+   return sin( ( M_PI * x ) / ( 2.0 * smoothing ) );
+}
+
+template< typename Real >
+__cuda_callable__
+Real positivePart( const Real& arg)
+{
+   return arg > 0.0 ? arg : 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real negativePart( const Real& arg)
+{
+   return arg < 0.0 ? arg : 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real ArgAbsMin( const Real& x, const Real& y )
+{
+   return fabs( x ) < fabs( y ) ?  x : y;
+}
+
+template< typename Real >
+__cuda_callable__
+Real ArgAbsMax( const Real& x, const Real& y )
+{
+   return fabs( x ) > fabs( y ) ?  x : y;
+}
+
diff --git a/src/operators/tnlDirichletBoundaryConditions_impl.h b/src/operators/tnlDirichletBoundaryConditions_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..70d5e6f7915056de349fc91616c0dfeb682c3d8e
--- /dev/null
+++ b/src/operators/tnlDirichletBoundaryConditions_impl.h
@@ -0,0 +1,144 @@
+/***************************************************************************
+                          tnlDirichletBoundaryConditions_impl.h  -  description
+                             -------------------
+    begin                : Nov 17, 2014
+    copyright            : (C) 2014 by oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_
+#define TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_
+
+#include <functions/tnlFunctionAdapter.h>
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+void
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+configSetup( tnlConfigDescription& config,
+             const String& prefix )
+{
+   Function::configSetup( config );
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+bool
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+setup( const Config::ParameterContainer& parameters,
+       const String& prefix )
+{
+   return this->function.setup( parameters );
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+void
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+setFunction( const Function& function )
+{
+   this->function = function;
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+Function&
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+getFunction()
+{
+   return this->function;
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+const Function&
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+getFunction() const
+{
+   return *this->function;
+}
+
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+template< typename EntityType,
+          typename MeshFunction >
+__cuda_callable__
+const Real
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+operator()( const MeshFunction& u,
+            const EntityType& entity,            
+            const RealType& time ) const
+{
+   //static_assert( EntityType::getDimensions() == MeshEntitiesDimensions, "Wrong mesh entity dimensions." );
+   return tnlFunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time );
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+   template< typename EntityType >
+__cuda_callable__
+Index
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const EntityType& entity ) const
+{
+   return 1;
+}
+
+template< typename Mesh,
+          typename Function,
+          int MeshEntitiesDimensions,
+          typename Real,
+          typename Index >
+   template< typename Matrix,
+             typename EntityType,
+             typename MeshFunction >
+__cuda_callable__
+void
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const EntityType& entity,
+                    const MeshFunction& u,
+                    DofVectorType& b,
+                    Matrix& matrix ) const
+{
+   typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+   matrixRow.setElement( 0, index, 1.0 );
+   b[ index ] = tnlFunctionAdapter< MeshType, Function >::getValue( this->function, entity, time );
+}
+
+#endif /* TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_ */
diff --git a/src/operators/tnlNeumannReflectionBoundaryConditions.h b/src/operators/tnlNeumannReflectionBoundaryConditions.h
new file mode 100644
index 0000000000000000000000000000000000000000..86fe650a3dbd39de6bcb24691d7e901043c9830e
--- /dev/null
+++ b/src/operators/tnlNeumannReflectionBoundaryConditions.h
@@ -0,0 +1,126 @@
+#pragma once
+
+#include <TNL/Containers/StaticVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <TNL/Config/ParameterContainer.h>
+#include <functions/tnlConstantFunction.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlNeumannReflectionBoundaryConditions
+{
+
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNeumannReflectionBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
+   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+   typedef Containers::StaticVector< 1, RealType > VertexType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+
+   bool setup( const Config::ParameterContainer& parameters,
+              const String& prefix = "" );
+
+   template< typename EntityType,
+             typename MeshFunction >
+   __cuda_callable__
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,   
+                              const RealType& time = 0 ) const;
+
+   CoordinatesType tmp;
+
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
+   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+   typedef Containers::StaticVector< 2, RealType > VertexType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+   bool setup( const Config::ParameterContainer& parameters,
+              const String& prefix = "" );
+
+
+   template< typename EntityType,
+             typename MeshFunction >
+   __cuda_callable__
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,   
+                              const RealType& time = 0 ) const;
+
+
+   CoordinatesType tmp;
+
+
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public:
+
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
+   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+   typedef Containers::StaticVector< 3, RealType > VertexType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+
+
+   bool setup( const Config::ParameterContainer& parameters,
+              const String& prefix = "" );
+
+
+   template< typename EntityType,
+             typename MeshFunction >
+   __cuda_callable__
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,   
+                              const RealType& time = 0 ) const;
+
+   private:
+
+   CoordinatesType tmp;
+
+
+};
+
+#include <operators/tnlNeumannReflectionBoundaryConditions_impl.h>
+
+#endif	/* TNLNEUMANNREFLECTIONBOUNDARYCONDITIONS_H */
diff --git a/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h b/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d791383520bd267beae784fe640d012ddd3147e0
--- /dev/null
+++ b/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h
@@ -0,0 +1,171 @@
+#pragma once
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool
+tnlNeumannReflectionBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+setup( const Config::ParameterContainer& parameters,
+      const String& prefix )
+{
+   return true;
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename EntityType,
+             typename MeshFunction >
+__cuda_callable__
+const Real
+tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+operator()( const MeshFunction& u,
+            const EntityType& entity,
+            const RealType& time ) const
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+void tnlNeumannReflectionBoundaryConditions< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >::
+setBoundaryConditions( const RealType& time,
+                       const MeshType& mesh,
+                       const IndexType index,
+                       const CoordinatesType& coordinates,
+                       DofVectorType& u,
+                       DofVectorType& fu )
+{
+	tmp = coordinates;
+
+   if(coordinates.x() == 0)
+	   tmp.x() = 1;
+   else if(coordinates.x() == mesh. getDimensions().x() - 1)
+	   tmp.x() = coordinates.x() - 2;
+
+   u[ index ] = u[mesh.getCellIndex( tmp )];
+}
+
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool
+tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+setup( const Config::ParameterContainer& parameters,
+      const String& prefix )
+{
+   return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename EntityType,
+             typename MeshFunction >
+__cuda_callable__
+const Real
+tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+operator()( const MeshFunction& u,
+            const EntityType& entity,
+            const RealType& time ) const
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+void tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+setBoundaryConditions( const RealType& time,
+                       const MeshType& mesh,
+                       const IndexType index,
+                       const CoordinatesType& coordinates,
+                       DofVectorType& u,
+                       DofVectorType& fu )
+{
+
+	tmp = coordinates;
+
+   if(coordinates.x() == 0)
+	   tmp.x() = coordinates.x() + 2;
+   else if(coordinates.x() == mesh. getDimensions().x() - 1)
+	   tmp.x() = coordinates.x() - 2;
+
+   if(coordinates.y() == 0)
+	   tmp.y() = coordinates.y() + 2;
+   else if(coordinates.y() == mesh. getDimensions().y() - 1)
+	   tmp.y() = coordinates.y() - 2;
+
+   u[ index ] = u[mesh.getCellIndex( tmp )];
+}
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool
+tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+setup( const Config::ParameterContainer& parameters,
+      const String& prefix )
+{
+   return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename EntityType,
+             typename MeshFunction >
+__cuda_callable__
+const Real
+tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+operator()( const MeshFunction& u,
+            const EntityType& entity,
+            const RealType& time ) const
+
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+void tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+setBoundaryConditions( const RealType& time,
+                       const MeshType& mesh,
+                       const IndexType index,
+                       const CoordinatesType& coordinates,
+                       DofVectorType& u,
+                       DofVectorType& fu )
+{
+	tmp = coordinates;
+
+   if(coordinates.x() == 0)
+	   tmp.x() = coordinates.x() + 2;
+   else if(coordinates.x() == mesh. getDimensions().x() - 1)
+	   tmp.x() = coordinates.x() - 2;
+
+   if(coordinates.y() == 0)
+	   tmp.y() = coordinates.y() + 2;
+   else if(coordinates.y() == mesh. getDimensions().y() - 1)
+	   tmp.y() = coordinates.y() - 2;
+
+   if(coordinates.z() == 0)
+	   tmp.z() = coordinates.z() + 2;
+   else if(coordinates.z() == mesh. getDimensions().z() - 1)
+	   tmp.z() = coordinates.z() - 2;
+
+   u[ index ] = u[mesh.getCellIndex( tmp )];
+}
+
+
+
+#endif	/* TNLNEUMANNREFLECTIONBOUNDARYCONDITIONS_IMPL_H */
+
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
index c4d33c9b06b9942b35cd04c0c4ff069e1050c44a..16d1fe51fa458b60d0c3a648720380f9ce16eba7 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h
@@ -14,7 +14,7 @@
 
 #include <core/tnlObject.h>
 #include <core/Devices::Host.h>
-#include <core/vectors/tnlStaticVector.h>
+#include <TNL/Containers/StaticVector.h>
 #include <core/vectors/tnlVector.h>
 
 template< int Dimensions,
@@ -50,8 +50,8 @@ 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 > VertexType;
+   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;
@@ -78,13 +78,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
 
    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 );
 
@@ -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 );
 
@@ -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 String( "Meshes::Grid< " ) +
+          String( getMeshDimensions() ) + ", " +
+          String( ::getType< RealType >() ) + ", " +
+          String( Device :: getDeviceType() ) + ", " +
+          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();
 };
@@ -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 );
@@ -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() )
    {
@@ -826,8 +826,8 @@ 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 > VertexType;
+   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;
@@ -854,13 +854,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject
 
    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 );
 
@@ -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 );
 
@@ -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 String( "Meshes::Grid< " ) +
+          String( getMeshDimensions() ) + ", " +
+          String( ::getType< RealType >() ) + ", " +
+          String( Device :: getDeviceType() ) + ", " +
+          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();
 };
@@ -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 );
@@ -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() )
    {
diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
index db0228ff1685026ca9a9a55b86ba1195fa58f4b0..8773d9254fe7673a0c69e7961744a2900265dfd5 100644
--- a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
+++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h
@@ -53,8 +53,8 @@ class tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimens
       constexpr static int getMeshDimensions() { return meshDimensions; };
       
       
-      typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType;
-      typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType;
+      typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType;
+      typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType;
       typedef tnlTestGridEntity< GridType, entityDimensions, Config > ThisType;
       //typedef tnlTestNeighbourGridEntitiesStorage< ThisType > NeighbourGridEntitiesStorageType;