diff --git a/CMakeLists.txt b/CMakeLists.txt
index c40dec06b3dea0544da8fe3c2e3f81e81beb0a6f..66bc530444ea97b9a6630de9c11cd7db892a2fd3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -129,6 +129,8 @@ add_subdirectory(targets/libs/VirtualFluidsBasics)
 add_subdirectory(targets/libs/Core)
 
 add_subdirectory(targets/libs/GksMeshAdapter)
+add_subdirectory(targets/libs/GksVtkAdapter)
+add_subdirectory(targets/libs/GksGpu)
 
 if(HULC.BUILD_NUMERIC_TESTS)
  	add_subdirectory(3rdParty/fftw/fftw-3.3.7)
@@ -141,4 +143,3 @@ add_subdirectory(targets/apps/LBM/lbmTest)
 add_subdirectory(targets/apps/LBM/metisTest)
 
 add_subdirectory(targets/apps/GKS/gksTest)
-
diff --git a/src/Core/RealConstants.h b/src/Core/RealConstants.h
index ae79164f031a4722837cac09f90399f1c777d9fd..9bb5c980a1fb9fbe576fef794bf6440fe5c6cd71 100644
--- a/src/Core/RealConstants.h
+++ b/src/Core/RealConstants.h
@@ -1,5 +1,5 @@
-#ifndef Real_CONSTANT_H
-#define Real_CONSTANT_H
+#ifndef REAL_CONSTANT_H
+#define REAL_CONSTANT_H
 
 #include "VirtualFluidsDefinitions.h"
 
diff --git a/src/Core/VectorTypes.h b/src/Core/VectorTypes.h
index b013b1e3bba8c8748d391ebdffe9cd3195a774d6..155c54cdcb5c9d8346a807291c27dc75301fc101 100644
--- a/src/Core/VectorTypes.h
+++ b/src/Core/VectorTypes.h
@@ -1,6 +1,13 @@
 #ifndef VECTORTYPES_H
 #define VECTORTYPES_H
 
+#ifdef __CUDACC__
+#include <cuda_runtime.h>
+#else
+#define __host__
+#define __device__
+#endif
+
 #include <cmath>
 
 #include "VirtualFluidsDefinitions.h"
@@ -11,10 +18,10 @@
 struct VF_PUBLIC Vec3 {
     real x, y, z; 
 
-    Vec3(real x, real y, real z) : x(x), y(y), z(z) {}
-    Vec3() : x(zero), y(zero), z(zero) {}
+    __host__ __device__ Vec3(real x, real y, real z) : x(x), y(y), z(z) {}
+    __host__ __device__ Vec3() : x(zero), y(zero), z(zero) {}
 
-    real length() {
+    __host__ __device__ real length() {
         return std::sqrt( x*x + y*y + z*z );
     }
 };
diff --git a/src/GksGpu/DataBase/DataBase.cpp b/src/GksGpu/DataBase/DataBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbd629837c3bc13481bfef693583f276584e6cf1
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBase.cpp
@@ -0,0 +1,153 @@
+#include "DataBase.h"
+
+#include <string>
+
+#include "DataBaseAllocator.h"
+#include "DataBaseStruct.h"
+
+#include "GksMeshAdapter/GksMeshAdapter.h"
+
+DataBase::DataBase( std::string type ) 
+        : myAllocator    ( DataBaseAllocator::create( type ) ),
+          numberOfNodes      (0),
+          numberOfCells      (0),
+          numberOfFaces      (0),
+          numberOfLevels     (0),
+          numberOfCoarseGhostCells(0),
+          numberOfFineGhostCells(0),
+          cellToCell     (nullptr),
+          faceToCell     (nullptr),
+          parentCell     (nullptr),
+          faceCenter     (nullptr),
+          cellCenter     (nullptr),
+          faceIsWall     (nullptr),
+          fineToCoarse   (nullptr),
+          coarseToFine   (nullptr),
+          data           (nullptr),
+          dataUpdate     (nullptr),
+          massFlux       (nullptr)
+{
+}
+
+DataBase::~DataBase()
+{
+    this->myAllocator->freeMemory( shared_from_this() );
+}
+
+void DataBase::setMesh(GksMeshAdapter & adapter)
+{
+    this->numberOfNodes      = adapter.nodes.size();
+
+    this->numberOfCells      = adapter.cells.size();
+
+    this->numberOfFaces      = adapter.faces.size();
+
+    this->numberOfLevels     = adapter.numberOfLevels;
+
+    this->perLevelCount.resize( this->numberOfLevels );
+
+    for( uint level = 0; level < this->numberOfLevels; level++ ){
+
+        perLevelCount[ level ].numberOfBulkCells = adapter.numberOfBulkCellsPerLevel[ level ];
+        perLevelCount[ level ].startOfBulkCells  = adapter.startOfCellsPerLevel     [ level ];
+
+        perLevelCount[ level ].numberOfFacesX = adapter.numberOfFacesPerLevelXYZ[ 3 * level     ];
+        perLevelCount[ level ].startOfFacesX  = adapter.startOfFacesPerLevelXYZ [ 3 * level     ];
+
+        perLevelCount[ level ].numberOfFacesY = adapter.numberOfFacesPerLevelXYZ[ 3 * level + 1 ];
+        perLevelCount[ level ].startOfFacesY  = adapter.startOfFacesPerLevelXYZ [ 3 * level + 1 ];
+
+        perLevelCount[ level ].numberOfFacesZ = adapter.numberOfFacesPerLevelXYZ[ 3 * level + 2 ];
+        perLevelCount[ level ].startOfFacesZ  = adapter.startOfFacesPerLevelXYZ [ 3 * level + 2 ];
+
+        perLevelCount[ level ].numberOfFaces  = perLevelCount[ level ].numberOfFacesX
+                                              + perLevelCount[ level ].numberOfFacesY
+                                              + perLevelCount[ level ].numberOfFacesZ;
+
+        perLevelCount[ level ].numberOfFineToCoarse = adapter.numberOfFineToCoarsePerLevel[ level ];
+        perLevelCount[ level ].numberOfCoarseToFine = adapter.numberOfCoarseToFinePerLevel[ level ];
+
+        perLevelCount[ level ].startOfFineToCoarse = adapter.startOfFineToCoarsePerLevel[ level ];
+        perLevelCount[ level ].startOfCoarseToFine = adapter.startOfCoarseToFinePerLevel[ level ];
+    }
+
+    this->numberOfCoarseGhostCells = adapter.fineToCoarse.size();
+
+    this->numberOfFineGhostCells   = adapter.coarseToFine.size();
+
+    this->myAllocator->allocateMemory( shared_from_this() );
+
+    this->myAllocator->copyMesh( shared_from_this(), adapter );
+}
+
+void DataBase::copyDataHostToDevice()
+{
+    this->myAllocator->copyDataHostToDevice( shared_from_this() );
+}
+
+void DataBase::copyDataDeviceToHost()
+{
+    this->myAllocator->copyDataDeviceToHost( shared_from_this(), this->dataHost.data() );
+}
+
+void DataBase::copyDataDeviceToHost( real* dataHost )
+{
+    this->myAllocator->copyDataDeviceToHost( shared_from_this(), dataHost );
+}
+
+DataBaseStruct DataBase::toStruct()
+{
+    DataBaseStruct dataBase;
+
+    dataBase.numberOfCells            = this->numberOfCells;
+    dataBase.numberOfFaces            = this->numberOfFaces;
+
+    dataBase.numberOfCoarseGhostCells = this->numberOfCoarseGhostCells;
+    dataBase.numberOfFineGhostCells   = this->numberOfFineGhostCells;
+
+    dataBase.cellToCell               = this->cellToCell;
+    dataBase.faceToCell               = this->faceToCell;
+
+    dataBase.fineToCoarse             = this->fineToCoarse;
+    dataBase.coarseToFine             = this->coarseToFine;
+
+    dataBase.faceCenter               = this->faceCenter;
+    dataBase.cellCenter               = this->cellCenter;
+
+    dataBase.faceIsWall               = this->faceIsWall;
+
+    dataBase.fineToCoarse             = this->fineToCoarse;
+    dataBase.coarseToFine             = this->coarseToFine;
+
+    dataBase.data                     = this->data;
+    dataBase.dataUpdate               = this->dataUpdate;
+
+    dataBase.massFlux                 = this->massFlux;
+
+    return dataBase;
+}
+
+uint DataBase::getCellLevel(uint cellIdx)
+{
+    uint level = 0;
+
+    while( cellIdx < this->perLevelCount[level].startOfBulkCells
+                   + this->perLevelCount[level].numberOfBulkCells ) level++;
+
+    return level;
+}
+
+uint DataBase::getFaceLevel(uint faceIdx)
+{
+    uint level = 0;
+
+    while( faceIdx < this->perLevelCount[level].startOfFacesX
+                   + this->perLevelCount[level].numberOfFaces ) level++;
+
+    return level;
+}
+
+bool DataBase::isGhostCell(uint cellIdx)
+{
+    return cellIdx < this->perLevelCount[ this->getCellLevel( cellIdx ) ].numberOfBulkCells;
+}
diff --git a/src/GksGpu/DataBase/DataBase.h b/src/GksGpu/DataBase/DataBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..d15ff10c96f2b1eb49ab3d37c3c54030fc514d2f
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBase.h
@@ -0,0 +1,141 @@
+#ifndef DataBase_H
+#define DataBase_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "Core/DataTypes.h"
+#include "Core/VectorTypes.h"
+#include "Core/ArrayTypes.h"
+
+#include "VirtualFluidsDefinitions.h"
+
+class  GksMeshAdapter;
+
+class  DataBaseAllocator;
+struct DataBase;
+struct PerLevelCounts;
+struct DataBaseStruct;
+
+struct VF_PUBLIC DataBase : public std::enable_shared_from_this<DataBase>
+{
+    //////////////////////////////////////////////////////////////////////////
+    // Management
+    //////////////////////////////////////////////////////////////////////////
+
+    std::shared_ptr<DataBaseAllocator> myAllocator;
+
+    //////////////////////////////////////////////////////////////////////////
+    // Sizes
+    //////////////////////////////////////////////////////////////////////////
+
+    uint numberOfNodes;
+
+    uint numberOfCells;
+
+    uint numberOfFaces;
+
+    uint numberOfLevels;
+
+    uint numberOfCoarseGhostCells;
+
+    uint numberOfFineGhostCells;
+
+    std::vector<PerLevelCounts> perLevelCount;
+
+    //////////////////////////////////////////////////////////////////////////
+    // Host only geometry and connectivity
+    //////////////////////////////////////////////////////////////////////////
+
+    std::vector<Vec3>   nodeCoordinates;
+
+    std::vector<uint_8> cellToNode;
+    std::vector<uint_4> faceToNode;
+
+    //////////////////////////////////////////////////////////////////////////
+    // Host/Device geometry and connectivity - READ ONLY
+    //////////////////////////////////////////////////////////////////////////
+
+    uint* cellToCell;     // 6
+
+    uint* faceToCell;     // 2
+
+    uint* parentCell;     // 1
+
+    real* faceCenter;     // 3
+    real* cellCenter;     // 3
+
+    bool* faceIsWall;     // 1
+
+    uint* fineToCoarse;   // 9
+    uint* coarseToFine;   // 15
+
+    //////////////////////////////////////////////////////////////////////////
+    // Host/Device data - READ MODIFY
+    //////////////////////////////////////////////////////////////////////////
+
+    real* data;
+    real* dataUpdate;
+
+    real* massFlux;
+
+    //////////////////////////////////////////////////////////////////////////
+    // Host only data
+    //////////////////////////////////////////////////////////////////////////
+
+    std::vector<real> dataHost;
+
+    //////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////
+    // Methods
+    //////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////
+
+    DataBase( std::string type );
+    ~DataBase();
+
+    //void setMesh( std::shared_ptr<MeshGeneratorQuadTree> mesh );
+
+    void setMesh( GksMeshAdapter& adapter );
+
+    void copyDataHostToDevice();
+
+    void copyDataDeviceToHost();
+
+    void copyDataDeviceToHost( real* dataHost );
+
+    DataBaseStruct toStruct();
+
+    //////////////////////////////////////////////////////////////////////////
+
+    uint getCellLevel( uint cellIdx );
+    uint getFaceLevel( uint faceIdx );
+
+    bool isGhostCell( uint cellIdx );
+};
+
+struct PerLevelCounts
+{
+    uint numberOfBulkCells;
+    uint startOfBulkCells;
+
+    uint numberOfFaces;
+
+    uint numberOfFacesX;
+    uint startOfFacesX;
+
+    uint numberOfFacesY;
+    uint startOfFacesY;
+
+    uint numberOfFacesZ;
+    uint startOfFacesZ;
+
+    uint numberOfCoarseToFine;
+    uint startOfCoarseToFine;
+
+    uint numberOfFineToCoarse;
+    uint startOfFineToCoarse;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/GksGpu/DataBase/DataBaseAllocator.cpp b/src/GksGpu/DataBase/DataBaseAllocator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38e073f16e7811ca8d07b4ca0eec72a2ed4f69de
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocator.cpp
@@ -0,0 +1,29 @@
+#include "DataBaseAllocator.h"
+
+//#include "../../DataBase/DataBaseAllocator/DataBaseAllocatorCPU/DataBaseAllocatorCPU.h"
+//#include "../../DataBase/DataBaseAllocator/DataBaseAllocatorGPU/DataBaseAllocatorGPU.h"
+
+#include "DataBaseAllocatorCPU.h"
+#include "DataBaseAllocatorGPU.h"
+
+#include <string>
+
+std::shared_ptr<DataBaseAllocator> DataBaseAllocator::create(std::string type)
+{
+    if ( type == "GPU" )
+        return std::shared_ptr<DataBaseAllocator>( new DataBaseAllocatorGPU() );
+    else
+        return std::shared_ptr<DataBaseAllocator>( new DataBaseAllocatorCPU() );
+}
+
+DataBaseAllocator::~DataBaseAllocator()
+{
+}
+
+DataBaseAllocator::DataBaseAllocator()
+{
+}
+
+DataBaseAllocator::DataBaseAllocator(const DataBaseAllocator & orig)
+{
+}
diff --git a/src/GksGpu/DataBase/DataBaseAllocator.h b/src/GksGpu/DataBase/DataBaseAllocator.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f4c75e269e09b26dbe60061bf9471c372c85238
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocator.h
@@ -0,0 +1,39 @@
+#ifndef DataBaseAllocator_H
+#define DataBaseAllocator_H
+
+#include <string>
+
+#include "Core/DataTypes.h"
+#include "Core/PointerDefinitions.h"
+
+#include <VirtualFluidsDefinitions.h>
+
+class  GksMeshAdapter;
+struct DataBase;
+
+class VF_PUBLIC DataBaseAllocator {
+
+public:
+    virtual void freeMemory( SPtr<DataBase> dataBase ) = 0;
+
+    virtual void allocateMemory( SPtr<DataBase> dataBase) = 0;
+
+    virtual void copyMesh( SPtr<DataBase> dataBase, GksMeshAdapter& adapter ) = 0;
+
+    virtual void copyDataHostToDevice( SPtr<DataBase> dataBase ) = 0;
+    
+    virtual void copyDataDeviceToHost( SPtr<DataBase> dataBase, real* hostData ) = 0;
+
+    static std::shared_ptr<DataBaseAllocator> create( std::string type );
+
+    ~DataBaseAllocator();
+
+protected:
+
+    DataBaseAllocator();
+    DataBaseAllocator( const DataBaseAllocator& orig );
+
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/GksGpu/DataBase/DataBaseAllocatorCPU.cpp b/src/GksGpu/DataBase/DataBaseAllocatorCPU.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68c755dbb0d9de7b778864397514717ab5a01997
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocatorCPU.cpp
@@ -0,0 +1,132 @@
+#include "DataBaseAllocatorCPU.h"
+
+#include <cstring>
+
+#include "Core/DataTypes.h"
+#include "Core/PointerDefinitions.h"
+
+#include "GksMeshAdapter/GksMeshAdapter.h"
+
+#include "DataBase.h"
+
+#include "Definitions/MemoryAccessPattern.h"
+
+void DataBaseAllocatorCPU::freeMemory( SPtr<DataBase> dataBase)
+{
+    dataBase->cellToNode.clear();
+    dataBase->faceToNode.clear();
+
+    delete [] dataBase->cellToCell;
+
+    delete [] dataBase->faceToCell;
+
+    delete [] dataBase->parentCell;
+
+    delete [] dataBase->faceCenter;
+    delete [] dataBase->cellCenter;
+
+    delete [] dataBase->faceIsWall;
+
+    delete [] dataBase->fineToCoarse;
+    delete [] dataBase->coarseToFine;
+
+    delete [] dataBase->data;
+    delete [] dataBase->dataUpdate;
+
+    delete [] dataBase->massFlux;
+
+    dataBase->dataHost.clear();
+}
+
+void DataBaseAllocatorCPU::allocateMemory(SPtr<DataBase> dataBase)
+{
+    dataBase->cellToNode.resize( dataBase->numberOfCells );
+    dataBase->faceToNode.resize( dataBase->numberOfFaces );
+
+    dataBase->cellToCell = new uint [ LENGTH_CELL_TO_CELL * dataBase->numberOfCells ];
+
+    dataBase->faceToCell = new uint [ LENGTH_FACE_TO_CELL * dataBase->numberOfFaces ];
+
+    dataBase->faceCenter = new real [ LENGTH_VECTOR * dataBase->numberOfFaces ];
+    dataBase->cellCenter = new real [ LENGTH_VECTOR * dataBase->numberOfCells ];
+
+    dataBase->faceIsWall = new bool [ dataBase->numberOfFaces ];
+
+    dataBase->fineToCoarse = new uint [ LENGTH_FINE_TO_COARSE * dataBase->numberOfCoarseGhostCells ];
+    dataBase->coarseToFine = new uint [ LENGTH_COARSE_TO_FINE * dataBase->numberOfFineGhostCells   ];
+
+    dataBase->data       = new real [ LENGTH_CELL_DATA * dataBase->numberOfCells ];
+    dataBase->dataUpdate = new real [ LENGTH_CELL_DATA * dataBase->numberOfCells ];
+
+    dataBase->massFlux   = new real [ LENGTH_VECTOR    * dataBase->numberOfCells ];
+
+    dataBase->dataHost.resize( LENGTH_CELL_DATA * dataBase->numberOfCells );
+}
+
+void DataBaseAllocatorCPU::copyMesh(SPtr<DataBase> dataBase, GksMeshAdapter & adapter)
+{
+    dataBase->nodeCoordinates = adapter.nodes;
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfCells; cellIdx++ )
+    {
+        dataBase->cellToNode[ cellIdx ][ 0 ] = adapter.cells[ cellIdx ].cellToNode[ 7 ];
+        dataBase->cellToNode[ cellIdx ][ 1 ] = adapter.cells[ cellIdx ].cellToNode[ 3 ];
+        dataBase->cellToNode[ cellIdx ][ 2 ] = adapter.cells[ cellIdx ].cellToNode[ 1 ];
+        dataBase->cellToNode[ cellIdx ][ 3 ] = adapter.cells[ cellIdx ].cellToNode[ 5 ];
+        dataBase->cellToNode[ cellIdx ][ 4 ] = adapter.cells[ cellIdx ].cellToNode[ 6 ];
+        dataBase->cellToNode[ cellIdx ][ 5 ] = adapter.cells[ cellIdx ].cellToNode[ 2 ];
+        dataBase->cellToNode[ cellIdx ][ 6 ] = adapter.cells[ cellIdx ].cellToNode[ 0 ];
+        dataBase->cellToNode[ cellIdx ][ 7 ] = adapter.cells[ cellIdx ].cellToNode[ 4 ];
+        
+        for( uint neighbordx = 0; neighbordx < LENGTH_CELL_TO_CELL; neighbordx++ )
+            dataBase->cellToCell[ CELL_TO_CELL( cellIdx, neighbordx, dataBase->numberOfCells ) ] 
+                = adapter.cells[ cellIdx ].cellToCell[ neighbordx ];
+
+        dataBase->cellCenter[ VEC_X( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.x;
+        dataBase->cellCenter[ VEC_Y( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.y;
+        dataBase->cellCenter[ VEC_Z( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.z;
+    }
+
+    for( uint faceIdx = 0; faceIdx < dataBase->numberOfFaces; faceIdx++ )
+    {
+        for( uint nodeIdx = 0; nodeIdx < 4; nodeIdx++ )
+            dataBase->faceToNode[ faceIdx ][ nodeIdx ]
+                = adapter.faces[ faceIdx ].faceToNode[ nodeIdx ];
+
+        dataBase->faceToCell[ NEG_CELL( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].negCell;
+        dataBase->faceToCell[ POS_CELL( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].posCell;
+
+        dataBase->faceCenter[ VEC_X( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].faceCenter.x;
+        dataBase->faceCenter[ VEC_Y( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].faceCenter.y;
+
+        dataBase->faceIsWall[ faceIdx ] = adapter.faces[ faceIdx ].isWall;
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint idx = 0; idx < dataBase->numberOfCoarseGhostCells; idx++ ){
+        for( uint connectivityIdx = 0; connectivityIdx < LENGTH_FINE_TO_COARSE; connectivityIdx++ ){
+            dataBase->fineToCoarse[ FINE_TO_COARSE( idx, connectivityIdx, dataBase->numberOfCoarseGhostCells ) ]
+                = adapter.fineToCoarse[idx][connectivityIdx];
+        }
+    }
+
+    for( uint idx = 0; idx < dataBase->numberOfFineGhostCells; idx++ ){
+        for( uint connectivityIdx = 0; connectivityIdx < LENGTH_COARSE_TO_FINE; connectivityIdx++ ){
+            dataBase->coarseToFine[ COARSE_TO_FINE( idx, connectivityIdx, dataBase->numberOfFineGhostCells ) ]
+                = adapter.coarseToFine[idx][connectivityIdx];
+        }
+    }
+}
+
+void DataBaseAllocatorCPU::copyDataHostToDevice(SPtr<DataBase> dataBase)
+{
+    memcpy( dataBase->data, dataBase->dataHost.data(), sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells );
+}
+
+void DataBaseAllocatorCPU::copyDataDeviceToHost(SPtr<DataBase> dataBase, real* hostData)
+{
+    memcpy( hostData, dataBase->data, sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells );
+}
diff --git a/src/GksGpu/DataBase/DataBaseAllocatorCPU.h b/src/GksGpu/DataBase/DataBaseAllocatorCPU.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d26db7ec54bb024a2147af7ae516eed1eb67bd4
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocatorCPU.h
@@ -0,0 +1,27 @@
+#ifndef DataBaseAllocatorCPU_H
+#define DatabaseAllocatorCPU_H
+
+#include "Core/DataTypes.h"
+#include "Core/PointerDefinitions.h"
+
+#include "DataBaseAllocator.h"
+
+#include <VirtualFluidsDefinitions.h>
+
+class VF_PUBLIC DataBaseAllocatorCPU: public DataBaseAllocator {
+
+public:
+
+    virtual void freeMemory( SPtr<DataBase> dataBase ) override;
+
+    virtual void allocateMemory( SPtr<DataBase> dataBase ) override;
+
+    virtual void copyMesh( SPtr<DataBase> dataBase, GksMeshAdapter& adapter ) override;
+
+    virtual void copyDataHostToDevice( SPtr<DataBase> dataBase ) override;
+    
+    virtual void copyDataDeviceToHost( SPtr<DataBase> dataBase, real* dataHost ) override;
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/GksGpu/DataBase/DataBaseAllocatorGPU.cpp b/src/GksGpu/DataBase/DataBaseAllocatorGPU.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad6be612e98b79be4d1ac7a42da53cef1e4bfa31
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocatorGPU.cpp
@@ -0,0 +1,167 @@
+#include "DataBaseAllocatorGPU.h"
+
+#include <cstring>
+#include <cuda.h>
+#include <cuda_runtime.h>
+#include <helper_cuda.h>
+
+#include "Core/DataTypes.h"
+#include "Core/PointerDefinitions.h"
+
+#include "GksMeshAdapter/GksMeshAdapter.h"
+
+#include "DataBase/DataBase.h"
+
+#include "Definitions/MemoryAccessPattern.h"
+
+void DataBaseAllocatorGPU::freeMemory( SPtr<DataBase> dataBase )
+{
+    dataBase->cellToNode.clear();
+    dataBase->faceToNode.clear();
+
+    checkCudaErrors( cudaFree ( dataBase->cellToCell ) );
+
+    checkCudaErrors( cudaFree ( dataBase->faceToCell ) );
+
+    checkCudaErrors( cudaFree ( dataBase->parentCell ) );
+
+    checkCudaErrors( cudaFree ( dataBase->faceCenter ) );
+    checkCudaErrors( cudaFree ( dataBase->cellCenter ) );
+
+    checkCudaErrors( cudaFree ( dataBase->faceIsWall ) );
+
+    checkCudaErrors( cudaFree ( dataBase->fineToCoarse ) );
+    checkCudaErrors( cudaFree ( dataBase->coarseToFine ) );
+
+    checkCudaErrors( cudaFree ( dataBase->data ) );
+    checkCudaErrors( cudaFree ( dataBase->dataUpdate ) );
+
+    checkCudaErrors( cudaFree ( dataBase->massFlux ) );
+
+    dataBase->dataHost.clear();
+}
+
+void DataBaseAllocatorGPU::allocateMemory(SPtr<DataBase> dataBase)
+{
+    dataBase->cellToNode.resize( dataBase->numberOfCells );
+    dataBase->faceToNode.resize( dataBase->numberOfFaces );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->cellToCell, sizeof(uint) * LENGTH_CELL_TO_CELL * dataBase->numberOfCells ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->faceToCell, sizeof(uint) * LENGTH_FACE_TO_CELL * dataBase->numberOfFaces ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->faceCenter, sizeof(real) * LENGTH_VECTOR * dataBase->numberOfFaces ) );
+    checkCudaErrors( cudaMalloc ( &dataBase->cellCenter, sizeof(real) * LENGTH_VECTOR * dataBase->numberOfCells ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->faceIsWall, sizeof(bool) * dataBase->numberOfFaces ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->fineToCoarse, sizeof(uint) * LENGTH_FINE_TO_COARSE * dataBase->numberOfCoarseGhostCells ) );
+    checkCudaErrors( cudaMalloc ( &dataBase->coarseToFine, sizeof(uint) * LENGTH_COARSE_TO_FINE * dataBase->numberOfFineGhostCells   ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->data,       sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells ) );
+    checkCudaErrors( cudaMalloc ( &dataBase->dataUpdate, sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells ) );
+
+    checkCudaErrors( cudaMalloc ( &dataBase->massFlux ,  sizeof(real) * LENGTH_VECTOR    * dataBase->numberOfCells ) );
+
+    dataBase->dataHost.resize( LENGTH_CELL_DATA * dataBase->numberOfCells );
+}
+
+void DataBaseAllocatorGPU::copyMesh(SPtr<DataBase> dataBase, GksMeshAdapter & adapter)
+{
+    dataBase->nodeCoordinates = adapter.nodes;
+
+    //////////////////////////////////////////////////////////////////////////
+
+    std::vector<uint> cellToCellBuffer   ( LENGTH_CELL_TO_CELL * dataBase->numberOfCells );
+
+    std::vector<uint> faceToCellBuffer   ( LENGTH_FACE_TO_CELL * dataBase->numberOfFaces );
+
+    std::vector<real> faceCenterBuffer   ( LENGTH_VECTOR * dataBase->numberOfFaces );
+    std::vector<real> cellCenterBuffer   ( LENGTH_VECTOR * dataBase->numberOfCells );
+
+    bool* faceIsWallBuffer = new bool[ dataBase->numberOfFaces ];
+
+    std::vector<uint> fineToCoarseBuffer ( LENGTH_FINE_TO_COARSE * dataBase->numberOfCoarseGhostCells );
+    std::vector<uint> coarseToFineBuffer ( LENGTH_COARSE_TO_FINE * dataBase->numberOfFineGhostCells   );
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfCells; cellIdx++ )
+    {
+        dataBase->cellToNode[ cellIdx ][ 0 ] = adapter.cells[ cellIdx ].cellToNode[ 7 ];
+        dataBase->cellToNode[ cellIdx ][ 1 ] = adapter.cells[ cellIdx ].cellToNode[ 3 ];
+        dataBase->cellToNode[ cellIdx ][ 2 ] = adapter.cells[ cellIdx ].cellToNode[ 1 ];
+        dataBase->cellToNode[ cellIdx ][ 3 ] = adapter.cells[ cellIdx ].cellToNode[ 5 ];
+        dataBase->cellToNode[ cellIdx ][ 4 ] = adapter.cells[ cellIdx ].cellToNode[ 6 ];
+        dataBase->cellToNode[ cellIdx ][ 5 ] = adapter.cells[ cellIdx ].cellToNode[ 2 ];
+        dataBase->cellToNode[ cellIdx ][ 6 ] = adapter.cells[ cellIdx ].cellToNode[ 0 ];
+        dataBase->cellToNode[ cellIdx ][ 7 ] = adapter.cells[ cellIdx ].cellToNode[ 4 ];
+        
+        for( uint neighbordx = 0; neighbordx < LENGTH_CELL_TO_CELL; neighbordx++ )
+            cellToCellBuffer[ CELL_TO_CELL( cellIdx, neighbordx, dataBase->numberOfCells ) ] 
+                = adapter.cells[ cellIdx ].cellToCell[ neighbordx ];
+
+        cellCenterBuffer[ VEC_X( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.x;
+        cellCenterBuffer[ VEC_Y( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.y;
+        cellCenterBuffer[ VEC_Z( cellIdx, dataBase->numberOfCells ) ] = adapter.cells[ cellIdx ].cellCenter.z;
+    }
+
+    for( uint faceIdx = 0; faceIdx < dataBase->numberOfFaces; faceIdx++ )
+    {
+        for( uint nodeIdx = 0; nodeIdx < 4; nodeIdx++ )
+            dataBase->faceToNode[ faceIdx ][ nodeIdx ]
+                = adapter.faces[ faceIdx ].faceToNode[ nodeIdx ];
+
+        faceToCellBuffer[ NEG_CELL( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].negCell;
+        faceToCellBuffer[ POS_CELL( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].posCell;
+
+        faceCenterBuffer[ VEC_X( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].faceCenter.x;
+        faceCenterBuffer[ VEC_Y( faceIdx, dataBase->numberOfFaces ) ] = adapter.faces[ faceIdx ].faceCenter.y;
+
+        faceIsWallBuffer[ faceIdx ] = adapter.faces[ faceIdx ].isWall;
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfCoarseGhostCells; cellIdx++ ){
+        for( uint connectivityIdx = 0; connectivityIdx < LENGTH_FINE_TO_COARSE; connectivityIdx++ ){
+            fineToCoarseBuffer[ FINE_TO_COARSE( cellIdx, connectivityIdx, dataBase->numberOfCoarseGhostCells ) ]
+                = adapter.fineToCoarse[cellIdx][connectivityIdx];
+        }
+    }
+
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfFineGhostCells; cellIdx++ ){
+        for( uint connectivityIdx = 0; connectivityIdx < LENGTH_COARSE_TO_FINE; connectivityIdx++ ){
+            coarseToFineBuffer[ COARSE_TO_FINE( cellIdx, connectivityIdx, dataBase->numberOfFineGhostCells ) ]
+                = adapter.coarseToFine[cellIdx][connectivityIdx];
+        }
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+
+    checkCudaErrors( cudaMemcpy ( dataBase->cellToCell, cellToCellBuffer.data(), sizeof(uint) * LENGTH_CELL_TO_CELL * dataBase->numberOfCells, cudaMemcpyHostToDevice ) );
+    
+    checkCudaErrors( cudaMemcpy ( dataBase->faceToCell, faceToCellBuffer.data(), sizeof(uint) * LENGTH_FACE_TO_CELL * dataBase->numberOfFaces, cudaMemcpyHostToDevice ) );
+
+    checkCudaErrors( cudaMemcpy ( dataBase->faceCenter, faceCenterBuffer.data(), sizeof(real) * LENGTH_VECTOR * dataBase->numberOfFaces, cudaMemcpyHostToDevice ) );
+    checkCudaErrors( cudaMemcpy ( dataBase->cellCenter, cellCenterBuffer.data(), sizeof(real) * LENGTH_VECTOR * dataBase->numberOfCells, cudaMemcpyHostToDevice ) );
+
+    checkCudaErrors( cudaMemcpy ( dataBase->faceIsWall, faceIsWallBuffer       , sizeof(bool) * dataBase->numberOfFaces, cudaMemcpyHostToDevice ) );
+
+    checkCudaErrors( cudaMemcpy ( dataBase->fineToCoarse, fineToCoarseBuffer.data(), sizeof(uint) * LENGTH_FINE_TO_COARSE * dataBase->numberOfCoarseGhostCells, cudaMemcpyHostToDevice ) );
+    checkCudaErrors( cudaMemcpy ( dataBase->coarseToFine, coarseToFineBuffer.data(), sizeof(uint) * LENGTH_COARSE_TO_FINE * dataBase->numberOfFineGhostCells  , cudaMemcpyHostToDevice ) );
+
+    //////////////////////////////////////////////////////////////////////////
+    
+    delete [] faceIsWallBuffer;
+}
+
+void DataBaseAllocatorGPU::copyDataHostToDevice(SPtr<DataBase> dataBase)
+{
+    checkCudaErrors( cudaMemcpy( dataBase->data, dataBase->dataHost.data(), sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells, cudaMemcpyHostToDevice ) );
+}
+
+void DataBaseAllocatorGPU::copyDataDeviceToHost(SPtr<DataBase> dataBase,  real* hostData )
+{
+    checkCudaErrors( cudaMemcpy( hostData, dataBase->data, sizeof(real) * LENGTH_CELL_DATA * dataBase->numberOfCells, cudaMemcpyDeviceToHost ) );
+}
diff --git a/src/GksGpu/DataBase/DataBaseAllocatorGPU.h b/src/GksGpu/DataBase/DataBaseAllocatorGPU.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca3bf02a7dd57a4a53f01b3e9ad48c6c4da86fc2
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseAllocatorGPU.h
@@ -0,0 +1,27 @@
+#ifndef DataBaseAllocatorGPU_H
+#define DatabaseAllocatorGPU_H
+
+#include "Core/DataTypes.h"
+#include "Core/PointerDefinitions.h"
+
+#include "DataBaseAllocator.h"
+
+#include <VirtualFluidsDefinitions.h>
+
+class VF_PUBLIC DataBaseAllocatorGPU : public DataBaseAllocator {
+
+public:
+
+    virtual void freeMemory( SPtr<DataBase> dataBase ) override;
+
+    virtual void allocateMemory( SPtr<DataBase> dataBase ) override;
+
+    virtual void copyMesh( SPtr<DataBase> dataBase, GksMeshAdapter& adapter ) override;
+
+    virtual void copyDataHostToDevice( SPtr<DataBase> dataBase ) override;
+    
+    virtual void copyDataDeviceToHost( SPtr<DataBase> dataBase, real* dataHost ) override;
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/GksGpu/DataBase/DataBaseStruct.h b/src/GksGpu/DataBase/DataBaseStruct.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa7d28dde55318b8fd87aedf1c8735bd04b7d0af
--- /dev/null
+++ b/src/GksGpu/DataBase/DataBaseStruct.h
@@ -0,0 +1,36 @@
+#ifndef DataBaseStruct_H
+#define DataBaseStruct_H
+
+#include "Core/DataTypes.h"
+
+#include <VirtualFluidsDefinitions.h>
+
+struct VF_PUBLIC DataBaseStruct
+{
+    uint  numberOfCells;
+    uint  numberOfFaces;
+    
+    uint  numberOfCoarseGhostCells;
+    uint  numberOfFineGhostCells;
+
+    uint* cellToCell;
+    uint* faceToCell;
+
+    uint* parentCell;
+
+    uint* fineToCoarse;
+    uint* coarseToFine;
+
+    real* faceCenter;
+    real* cellCenter;
+
+    bool* faceIsWall;
+
+    real* data;
+    real* dataUpdate;
+
+    real* massFlux;
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/GksGpu/DataBase/package.include b/src/GksGpu/DataBase/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/Definitions/MemoryAccessPattern.h b/src/GksGpu/Definitions/MemoryAccessPattern.h
new file mode 100644
index 0000000000000000000000000000000000000000..a45e2397c6989d3316a3847b9ef93fe4aba7048c
--- /dev/null
+++ b/src/GksGpu/Definitions/MemoryAccessPattern.h
@@ -0,0 +1,84 @@
+#ifndef DataDefinitions_H
+#define DataDefinitions_H
+
+#include "PassiveScalar.h"
+
+#define SOA
+
+//////////////////////////////////////////////////////////////////////////
+
+#define LENGTH_VECTOR       3
+
+#ifdef USE_PASSIVE_SCALAR
+    #define LENGTH_CELL_DATA    6
+#else
+    #define LENGTH_CELL_DATA    5
+#endif
+
+#define LENGTH_CELL_TO_CELL 6
+
+#define LENGTH_FACE_TO_CELL 2
+
+#define LENGTH_FINE_TO_COARSE 9
+
+#define LENGTH_COARSE_TO_FINE 15
+
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef SOA
+
+#define VEC_X(vecIdx, numberOfVectors)  ( 0 * numberOfVectors + vecIdx )
+#define VEC_Y(vecIdx, numberOfVectors)  ( 1 * numberOfVectors + vecIdx )
+#define VEC_Z(vecIdx, numberOfVectors)  ( 2 * numberOfVectors + vecIdx )
+                                                           
+#define RHO__( cellIdx, numberOfCells ) ( 0 * numberOfCells   + cellIdx )
+#define RHO_U( cellIdx, numberOfCells ) ( 1 * numberOfCells   + cellIdx )
+#define RHO_V( cellIdx, numberOfCells ) ( 2 * numberOfCells   + cellIdx )
+#define RHO_W( cellIdx, numberOfCells ) ( 3 * numberOfCells   + cellIdx )
+#define RHO_E( cellIdx, numberOfCells ) ( 4 * numberOfCells   + cellIdx )
+
+#ifdef USE_PASSIVE_SCALAR
+    #define RHO_S( cellIdx, numberOfCells ) ( 5 * numberOfCells   + cellIdx )
+#endif // USE_PASSIVE_SCALAR
+
+#define CELL_TO_CELL( cellIdx, neighborIdx, numberOfCells ) ( neighborIdx * numberOfCells + cellIdx )
+
+#define NEG_CELL( faceIdx, numberOfFaces ) (                 faceIdx )
+#define POS_CELL( faceIdx, numberOfFaces ) ( numberOfFaces + faceIdx )
+
+#define FINE_TO_COARSE( idx, cellIdx, number ) ( cellIdx * number + idx )
+#define COARSE_TO_FINE( idx, cellIdx, number ) ( cellIdx * number + idx )
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef AOS
+
+#define VEC_X(vecIdx, numberOfVectors)  ( vecIdx * LENGTH_VECTOR     )
+#define VEC_Y(vecIdx, numberOfVectors)  ( vecIdx * LENGTH_VECTOR + 1 )
+#define VEC_Z(vecIdx, numberOfVectors)  ( vecIdx * LENGTH_VECTOR + 2 )
+                                                           
+#define RHO__( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA     )
+#define RHO_U( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA + 1 )
+#define RHO_V( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA + 2 )
+#define RHO_W( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA + 3 )
+#define RHO_E( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA + 4 )
+
+#ifdef USE_PASSIVE_SCALAR
+    #define RHO_S( cellIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_DATA + 5 )
+#endif // USE_PASSIVE_SCALAR
+                                                                         
+#define CELL_TO_CELL( cellIdx, neighborIdx, numberOfCells ) ( cellIdx * LENGTH_CELL_TO_CELL + neighborIdx )
+
+#define NEG_CELL( faceIdx, numberOfFaces ) ( faceIdx * LENGTH_FACE_TO_CELL     )
+#define POS_CELL( faceIdx, numberOfFaces ) ( faceIdx * LENGTH_FACE_TO_CELL + 1 )
+
+#define FINE_TO_COARSE( idx, cellIdx, number ) ( cellIdx * LENGTH_FINE_TO_COARSE + idx )
+#define COARSE_TO_FINE( idx, cellIdx, number ) ( cellIdx * LENGTH_COARSE_TO_FINE + idx )
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/src/GksGpu/Definitions/PassiveScalar.h b/src/GksGpu/Definitions/PassiveScalar.h
new file mode 100644
index 0000000000000000000000000000000000000000..97fca44e5285a9b9850ba5690eae0a420ce60449
--- /dev/null
+++ b/src/GksGpu/Definitions/PassiveScalar.h
@@ -0,0 +1,6 @@
+#ifndef PassiveScalar_H
+#define PassiveScalar_H
+
+#define USE_PASSIVE_SCALAR
+
+#endif
diff --git a/src/GksGpu/Definitions/package.include b/src/GksGpu/Definitions/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/FlowStateData/FlowStateData.cuh b/src/GksGpu/FlowStateData/FlowStateData.cuh
new file mode 100644
index 0000000000000000000000000000000000000000..b304edfd62df7b643f268ca16130ac073090d9e2
--- /dev/null
+++ b/src/GksGpu/FlowStateData/FlowStateData.cuh
@@ -0,0 +1,155 @@
+#ifndef FlowStateData_H
+#define FlowStateData_H
+
+#ifdef __CUDACC__
+#include <cuda_runtime.h>
+#else
+#define __host__
+#define __device__
+#endif
+
+#include "Core/DataTypes.h"
+#include "Core/RealConstants.h"
+
+#include "Definitions/PassiveScalar.h"
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+struct PrimitiveVariables
+{
+    real rho;
+    real U;
+    real V;
+    real W;
+    real lambda;
+    #ifdef USE_PASSIVE_SCALAR
+    real S;
+    #endif
+
+    //////////////////////////////////////////////////////////////////////////
+
+    __host__ __device__ PrimitiveVariables()
+		: rho   (zero)
+         ,U     (zero)
+         ,V     (zero)
+         ,W     (zero)
+         ,lambda(zero)
+    #ifdef USE_PASSIVE_SCALAR
+         ,S     (zero)
+    #endif
+    {}
+
+    //////////////////////////////////////////////////////////////////////////
+
+    __host__ __device__ PrimitiveVariables(real rho
+                                          ,real U
+                                          ,real V
+                                          ,real W
+                                          ,real lambda
+    #ifdef USE_PASSIVE_SCALAR
+                                          ,real S
+    #endif
+    )
+        : rho   (rho   )
+         ,U     (U     )
+         ,V     (V     )
+         ,W     (W     )
+         ,lambda(lambda)
+    #ifdef USE_PASSIVE_SCALAR
+         ,S     (S     )
+    #endif
+    {}
+
+    //////////////////////////////////////////////////////////////////////////
+};
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+struct ConservedVariables
+{
+    real rho;
+    real rhoU;
+    real rhoV;
+    real rhoW;
+    real rhoE;
+    #ifdef USE_PASSIVE_SCALAR
+    real rhoS;
+    #endif
+
+    //////////////////////////////////////////////////////////////////////////
+
+    __host__ __device__ ConservedVariables()
+        : rho (zero)
+         ,rhoU(zero)
+         ,rhoV(zero)
+         ,rhoW(zero)
+         ,rhoE(zero)
+    #ifdef USE_PASSIVE_SCALAR
+         ,rhoS(zero)
+    #endif
+    {}
+
+    //////////////////////////////////////////////////////////////////////////
+		  
+    __host__ __device__ ConservedVariables(real rho
+                                          ,real rhoU
+                                          ,real rhoV
+                                          ,real rhoW
+                                          ,real rhoE
+    #ifdef USE_PASSIVE_SCALAR
+                                          ,real rhoS
+    #endif
+    )
+        : rho (rho )
+         ,rhoU(rhoU)
+         ,rhoV(rhoV)
+         ,rhoW(rhoW)
+         ,rhoE(rhoE)
+    #ifdef USE_PASSIVE_SCALAR
+         ,rhoS(rhoS)
+    #endif
+    {}
+
+    //////////////////////////////////////////////////////////////////////////
+};
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+__host__ __device__ inline ConservedVariables toConservedVariables( const PrimitiveVariables& prim, real K )
+{
+    return ConservedVariables(prim.rho
+                             ,prim.U * prim.rho
+                             ,prim.V * prim.rho
+                             ,prim.W * prim.rho
+                             ,( K + two ) / ( four * prim.lambda ) * prim.rho + c1o2 * prim.rho * ( prim.U * prim.U + prim.V * prim.V + prim.W * prim.W )
+    #ifdef USE_PASSIVE_SCALAR
+                             ,prim.S * prim.rho
+    #endif
+    );
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+__host__ __device__ inline PrimitiveVariables toPrimitiveVariables( const ConservedVariables& cons, real K )
+{
+	return PrimitiveVariables(cons.rho
+						     ,cons.rhoU / cons.rho
+						     ,cons.rhoV / cons.rho
+						     ,cons.rhoW / cons.rho
+						     ,( K + two ) * cons.rho / ( four * ( cons.rhoE - c1o2 * ( cons.rhoU * cons.rhoU + cons.rhoV * cons.rhoV + cons.rhoW * cons.rhoW ) / cons.rho ) )
+    #ifdef USE_PASSIVE_SCALAR
+                             ,cons.rhoS / cons.rho
+    #endif
+	);
+}
+
+#endif
+
diff --git a/src/GksGpu/FlowStateData/package.include b/src/GksGpu/FlowStateData/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/FluxEvaluation/package.include b/src/GksGpu/FluxEvaluation/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/FluxEvaluation/utilityKernels.cu b/src/GksGpu/FluxEvaluation/utilityKernels.cu
new file mode 100644
index 0000000000000000000000000000000000000000..f74b7c6c7c3d52ca9b21e70e6dd5faecad91f31e
--- /dev/null
+++ b/src/GksGpu/FluxEvaluation/utilityKernels.cu
@@ -0,0 +1,34 @@
+#include <cstdio>
+#include <cuda_runtime.h>
+#include <device_launch_parameters.h>
+
+#include "DataBase/DataBaseStruct.h"
+
+#define THREADS_PER_BLOCK 128
+
+__global__ void dummyKernel();
+
+__global__ void debugKernel( const DataBaseStruct dataBase );
+
+//////////////////////////////////////////////////////////////////////////
+
+__global__ void dummyKernel(  )
+{
+    printf("I am thread %d.\n", threadIdx.x);
+}
+
+__global__ void debugKernel( const DataBaseStruct dataBase )
+{   
+    if( threadIdx.x + blockIdx.x == 0 ){
+        printf("numberOfCells     : %d\n", dataBase.numberOfCells     );
+        printf("numberOfFaces     : %d\n", dataBase.numberOfFaces     );
+        printf("\n");
+        printf("\n");
+        printf("faceToCell: %p\n", dataBase.faceToCell);
+        printf("faceCenter: %p\n", dataBase.faceCenter);
+        printf("cellCenter: %p\n", dataBase.cellCenter);
+        printf("\n");
+        printf("data      : %p\n", dataBase.data      );
+        printf("dataNew   : %p\n", dataBase.dataUpdate);
+    }
+}
diff --git a/src/GksGpu/Initializer/Initializer.cu b/src/GksGpu/Initializer/Initializer.cu
new file mode 100644
index 0000000000000000000000000000000000000000..894bb32bf7777a4b5d7d0dc6277c65f79f137cb3
--- /dev/null
+++ b/src/GksGpu/Initializer/Initializer.cu
@@ -0,0 +1,54 @@
+#include "Initializer.h"
+
+#include <sstream>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <device_launch_parameters.h>
+#include <cuda.h>
+#include <cuda_runtime.h>
+
+#include "Core/PointerDefinitions.h"
+#include "Core/RealConstants.h"
+
+#include "DataBase/DataBaseStruct.h"
+
+#include <helper_cuda.h>
+
+#include "Definitions/MemoryAccessPattern.h"
+#include "Definitions/PassiveScalar.h"
+
+void Initializer::interpret(SPtr<DataBase> dataBase, std::function<ConservedVariables(Vec3)> initialCondition)
+{
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfCells; cellIdx++ ){
+
+        Vec3 cellCenter = getCellCenter(dataBase, cellIdx);
+
+        ConservedVariables cellCons = initialCondition(cellCenter);
+
+        dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ] = cellCons.rho ;
+        dataBase->dataHost[ RHO_U(cellIdx, dataBase->numberOfCells) ] = cellCons.rhoU;
+        dataBase->dataHost[ RHO_V(cellIdx, dataBase->numberOfCells) ] = cellCons.rhoV;
+        dataBase->dataHost[ RHO_E(cellIdx, dataBase->numberOfCells) ] = cellCons.rhoE;
+    #ifdef USE_PASSIVE_SCALAR
+	    dataBase->dataHost[ RHO_S(cellIdx, dataBase->numberOfCells) ] = cellCons.rhoS;
+    #endif // USE_PASSIVE_SCALAR
+    }
+
+    return;
+}
+
+Vec3 Initializer::getCellCenter(std::shared_ptr<DataBase> dataBase, uint cellIdx)
+{
+    Vec3 cellCenter;
+
+    for( uint node = 0; node < 8; node++ )
+    {
+        cellCenter = cellCenter + dataBase->nodeCoordinates[ dataBase->cellToNode[ cellIdx ][ node ] ];
+    }
+
+    cellCenter.x /= eight;
+    cellCenter.y /= eight;
+    cellCenter.z /= eight;
+
+    return cellCenter;
+}
diff --git a/src/GksGpu/Initializer/Initializer.h b/src/GksGpu/Initializer/Initializer.h
new file mode 100644
index 0000000000000000000000000000000000000000..89dfc94c27de840b47c2f3e1590684557634a824
--- /dev/null
+++ b/src/GksGpu/Initializer/Initializer.h
@@ -0,0 +1,26 @@
+#ifndef  Initializer_H
+#define  Initializer_H
+
+#include <string>
+#include <memory>
+#include <functional>
+
+#include "VirtualFluidsDefinitions.h"
+
+#include "Core/DataTypes.h"
+#include "Core/VectorTypes.h"
+
+#include "DataBase/DataBase.h"
+#include "FlowStateData/FlowStateData.cuh"
+
+struct PrimitiveVariables;
+
+class VF_PUBLIC Initializer
+{
+public:
+    static void interpret( std::shared_ptr<DataBase> dataBase, std::function<ConservedVariables(Vec3)> initialCondition );
+
+    static Vec3 getCellCenter( std::shared_ptr<DataBase> dataBase, uint cellIdx );
+};
+
+#endif
diff --git a/src/GksGpu/Initializer/package.include b/src/GksGpu/Initializer/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/Parameters/Parameters.h b/src/GksGpu/Parameters/Parameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..6227411d9820eed68d0fe1de1f558b0581b93c23
--- /dev/null
+++ b/src/GksGpu/Parameters/Parameters.h
@@ -0,0 +1,37 @@
+#ifndef Parameters_H
+#define Parameters_H
+
+#include "Core/DataTypes.h"
+#include "Core/VectorTypes.h"
+
+#include <VirtualFluidsDefinitions.h>
+
+enum class VF_PUBLIC ViscosityModel{
+    constant,
+    sutherlandsLaw
+};
+
+struct  VF_PUBLIC Parameters
+{
+
+    real mu = 0.01;
+    real K  = 1;
+    real Pr = 1.0;
+
+    real D  = 0.01;
+
+    real dt = 0.01;
+
+    real dx = 0.01;
+
+    Vec3 force;
+
+    real lambdaRef = 1.0;
+
+    ViscosityModel viscosityModel = ViscosityModel::constant;
+
+    real boussinesqT0   = 1.0;
+    real boussinesqBeta = 1.0;
+};
+
+#endif
diff --git a/src/GksGpu/Parameters/package.include b/src/GksGpu/Parameters/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksGpu/package.include b/src/GksGpu/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/GksMeshAdapter/GksMeshAdapter.cpp b/src/GksMeshAdapter/GksMeshAdapter.cpp
index e67b3fa1310bb074d05c3b947d696a0d196f6123..ba8d6525e5628d9801ec4d79fec2982ce08101bb 100644
--- a/src/GksMeshAdapter/GksMeshAdapter.cpp
+++ b/src/GksMeshAdapter/GksMeshAdapter.cpp
@@ -303,25 +303,29 @@ void GksMeshAdapter::generateNodes(SPtr<MultipleGridBuilder> gridBuilder)
                 cell.cellToNode[idx] = nodes.size()-1;
 
                 // register new node at neighbor cells on same level
-                for( uint idx = 0; idx < 8; idx++ )
+
+                for( uint neighborIdx = 0; neighborIdx < 27; neighborIdx++ )
                 {
-                    if( cell.cellToCell[idx] == INVALID_INDEX ) continue;
+                    if (cell.cellToCell[neighborIdx] == INVALID_INDEX) continue;
+
+                    for (uint idx = 0; idx < 8; idx++)
+                    {
+                        Distribution dirs = DistributionHelper::getDistribution27();
 
-                    Distribution dirs = DistributionHelper::getDistribution27();
+                        real dxNeighbor = -dirs.directions[idx + 19][0] * d;
+                        real dyNeighbor = -dirs.directions[idx + 19][1] * d;
+                        real dzNeighbor = -dirs.directions[idx + 19][2] * d;
 
-                    real dxNeighbor = - dirs.directions[idx + 19][0] * d;
-                    real dyNeighbor = - dirs.directions[idx + 19][1] * d;
-                    real dzNeighbor = - dirs.directions[idx + 19][2] * d;
-                    
-                    real xNeighbor = nodes.back().x + dx + dxNeighbor;
-                    real yNeighbor = nodes.back().y + dy + dyNeighbor;
-                    real zNeighbor = nodes.back().z + dz + dzNeighbor;
+                        real xNeighbor = nodes.back().x + dxNeighbor;
+                        real yNeighbor = nodes.back().y + dyNeighbor;
+                        real zNeighbor = nodes.back().z + dzNeighbor;
 
-                    uint neighborGridIdx = grids[cell.level]->transCoordToIndex( xNeighbor, yNeighbor, zNeighbor );
+                        uint neighborGridIdx = grids[cell.level]->transCoordToIndex(xNeighbor, yNeighbor, zNeighbor);
 
-                    if( neighborGridIdx != INVALID_INDEX && gridToMesh[ cell.level ][ neighborGridIdx ] == cell.cellToCell[idx] )
-                    {
-                        this->cells[ cell.cellToCell[idx] ].cellToNode[ idx ];
+                        if (neighborGridIdx != INVALID_INDEX && gridToMesh[cell.level][neighborGridIdx] == cell.cellToCell[neighborIdx])
+                        {
+                            this->cells[cell.cellToCell[neighborIdx]].cellToNode[idx] = nodes.size() - 1;
+                        }
                     }
                 }
             }
diff --git a/src/GksVtkAdapter/VTKAdapter.cpp b/src/GksVtkAdapter/VTKAdapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d9e87c8383a75e85390be8c0051d3e3eb43eced8
--- /dev/null
+++ b/src/GksVtkAdapter/VTKAdapter.cpp
@@ -0,0 +1,436 @@
+#include "VTKAdapter.h"
+#include "VTKInterface.h"
+
+#include <vtkImageData.h>
+
+#include <vtkCellData.h>
+#include <vtkPointData.h>
+
+#include <vtkResampleWithDataSet.h>
+#include <vtkPNGWriter.h>
+
+#include <vtkGeometryFilter.h>
+#include <vtkCleanPolyData.h>
+#include <vtkCellDataToPointData.h>
+#include <vtkPointDataToCellData.h>
+
+#include "Core/DataTypes.h"
+#include "Core/VectorTypes.h"
+
+#include "GksGpu/Definitions/MemoryAccessPattern.h"
+#include "GksGpu/FlowStateData/FlowStateData.cuh"
+
+vtkGridPtr getVtkUnstructuredOctGrid( SPtr<DataBase> dataBase, bool excludeGhostCells )
+{
+    vtkGridPtr grid = vtkGridPtr::New();
+ 
+    vtkPointsPtr points = vtkPointsPtr::New();
+ 
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint nodeIdx = 0; nodeIdx < dataBase->numberOfNodes; nodeIdx++ ){
+  
+        Vec3& node = dataBase->nodeCoordinates[ nodeIdx ];
+
+        points->InsertNextPoint( node.x, node.y, node.z );
+    }
+
+    grid->SetPoints( points );
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint cellIdx = 0; cellIdx < dataBase->numberOfCells; cellIdx++ ){
+
+        if( dataBase->isGhostCell( cellIdx ) && excludeGhostCells ) continue;
+
+        vtkIdListPtr idList = vtkIdListPtr::New();
+
+        idList->SetNumberOfIds( 8 );
+
+        idList->SetId( 0, dataBase->cellToNode[ cellIdx ][ 0 ] );
+        idList->SetId( 1, dataBase->cellToNode[ cellIdx ][ 1 ] );
+        idList->SetId( 2, dataBase->cellToNode[ cellIdx ][ 2 ] );
+        idList->SetId( 3, dataBase->cellToNode[ cellIdx ][ 3 ] );
+        idList->SetId( 4, dataBase->cellToNode[ cellIdx ][ 4 ] );
+        idList->SetId( 5, dataBase->cellToNode[ cellIdx ][ 5 ] );
+        idList->SetId( 6, dataBase->cellToNode[ cellIdx ][ 6 ] );
+        idList->SetId( 7, dataBase->cellToNode[ cellIdx ][ 7 ] );
+
+        grid->InsertNextCell( 12, idList );
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+
+    return grid;
+}
+
+void addScalarIntCellData( vtkGridPtr grid, 
+                        uint numberOfCells, 
+                        std::string name, 
+                        std::function<int(uint)> getData )
+{
+    vtkIntArrayPtr data = vtkIntArrayPtr::New();
+
+    data->SetNumberOfComponents( 1 );
+
+    data->SetName( name.c_str() );
+
+    for( uint cellIdx = 0; cellIdx < numberOfCells; cellIdx++ ){
+        data->InsertNextValue( getData(cellIdx) );
+    }
+
+    grid->GetCellData()->AddArray( data );
+}
+
+void addScalarRealCellData( vtkGridPtr grid, 
+                        uint numberOfCells, 
+                        std::string name, 
+                        std::function<real(uint)> getData )
+{
+    vtkDoubleArrayPtr data = vtkDoubleArrayPtr::New();
+
+    data->SetNumberOfComponents( 1 );
+
+    data->SetName( name.c_str() );
+
+    for( uint cellIdx = 0; cellIdx < numberOfCells; cellIdx++ ){
+        data->InsertNextValue( getData(cellIdx) );
+    }
+
+    grid->GetCellData()->AddArray( data );
+}
+
+void addVectorCellData( vtkGridPtr grid, 
+                        uint numberOfCells, 
+                        std::string name, 
+                        std::function<Vec3(uint)> getData )
+{
+    vtkDoubleArrayPtr data = vtkDoubleArrayPtr::New();
+
+    data->SetNumberOfComponents( 3 );
+
+    data->SetName( name.c_str() );
+
+    for( uint cellIdx = 0; cellIdx < numberOfCells; cellIdx++ ){
+        Vec3 vec = getData(cellIdx);
+        double tupel[3] = {vec.x, vec.y, vec.z};
+        data->InsertNextTuple(tupel);
+    }
+
+    grid->GetCellData()->AddArray( data );
+}
+
+void addBaseData(vtkGridPtr grid, SPtr<DataBase> dataBase, Parameters parameters)
+{
+    addScalarIntCellData( grid, dataBase->numberOfCells, "CellIdx", [&] (uint cellIdx) {
+        return cellIdx;
+    } );
+
+    addScalarRealCellData( grid, dataBase->numberOfCells, "rho", [&] (uint cellIdx) {
+        return dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ];
+    } );
+
+    addScalarRealCellData( grid, dataBase->numberOfCells, "T", [&] (uint cellIdx) {
+                    
+        ConservedVariables cons;
+
+        cons.rho  = dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoU = dataBase->dataHost[ RHO_U(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoV = dataBase->dataHost[ RHO_V(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoW = dataBase->dataHost[ RHO_W(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoE = dataBase->dataHost[ RHO_E(cellIdx, dataBase->numberOfCells) ];
+
+        PrimitiveVariables prim = toPrimitiveVariables(cons, parameters.K);
+
+        return 1.0 / prim.lambda;
+    } );
+
+    addScalarRealCellData( grid, dataBase->numberOfCells, "lambda", [&] (uint cellIdx) {
+                    
+        ConservedVariables cons;
+
+        cons.rho  = dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoU = dataBase->dataHost[ RHO_U(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoV = dataBase->dataHost[ RHO_V(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoW = dataBase->dataHost[ RHO_W(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoE = dataBase->dataHost[ RHO_E(cellIdx, dataBase->numberOfCells) ];
+
+        PrimitiveVariables prim = toPrimitiveVariables(cons, parameters.K);
+
+        return prim.lambda;
+    } );
+
+    addScalarRealCellData( grid, dataBase->numberOfCells, "p", [&] (uint cellIdx) {
+                    
+        ConservedVariables cons;
+
+        cons.rho  = dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoU = dataBase->dataHost[ RHO_U(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoV = dataBase->dataHost[ RHO_V(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoW = dataBase->dataHost[ RHO_W(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoE = dataBase->dataHost[ RHO_E(cellIdx, dataBase->numberOfCells) ];
+
+        PrimitiveVariables prim = toPrimitiveVariables(cons, parameters.K);
+
+        return 0.5 * prim.rho / prim.lambda;
+    } );
+
+    addScalarIntCellData( grid, dataBase->numberOfCells, "GhostCell", [&] (uint cellIdx) -> int {
+        return dataBase->isGhostCell( cellIdx );
+    } );
+
+    addScalarIntCellData( grid, dataBase->numberOfCells, "Level", [&] (uint cellIdx) {
+        return dataBase->getCellLevel(cellIdx);
+    } );
+            
+    addVectorCellData( grid, dataBase->numberOfCells, "Velocity", [&] (uint cellIdx) {
+                    
+        ConservedVariables cons;
+
+        cons.rho  = dataBase->dataHost[ RHO__(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoU = dataBase->dataHost[ RHO_U(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoV = dataBase->dataHost[ RHO_V(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoW = dataBase->dataHost[ RHO_W(cellIdx, dataBase->numberOfCells) ];
+        cons.rhoE = dataBase->dataHost[ RHO_E(cellIdx, dataBase->numberOfCells) ];
+
+        PrimitiveVariables prim = toPrimitiveVariables( cons, parameters.K );
+
+        return Vec3( prim.U, prim.V, prim.W );
+    } );
+
+#ifdef USE_PASSIVE_SCALAR
+	addScalarRealCellData( grid, dataBase->numberOfCells, "PassiveScalar", [&] (uint cellIdx) {
+	    return dataBase->dataHost[ RHO_S(cellIdx, dataBase->numberOfCells) ];
+	} );
+#endif // USE_PASSIVE_SCALAR
+
+}
+
+void writeVtkUnstructuredGrid( vtkGridPtr grid, int mode, std::string filename )
+{
+    vtkWriterPtr writer = vtkWriterPtr::New();
+
+    writer->SetDataMode(mode);
+
+    filename += ".";
+    filename += writer->GetDefaultFileExtension();
+
+    writer->SetFileName( filename.c_str() );
+
+    writer->SetInputData( grid );
+
+    writer->Write();
+}
+
+rgbColor colorMapCoolToWarmExtended( double value, double min, double max )
+{    
+    // Color map exported from Paraview
+    const double colorMap[36][3] = 
+    /*  0 */  { { 0,                      0,                      0.34902              },
+    /*  1 */    { 0.039216000000000001,   0.062744999999999995,   0.38039200000000001  },
+    /*  2 */    { 0.062744999999999995,   0.117647,               0.41176499999999999  },
+    /*  3 */    { 0.090195999999999998,   0.18431400000000001,    0.45097999999999999  },
+    /*  4 */    { 0.12548999999999999,    0.26274500000000001,    0.50196099999999999  },
+    /*  5 */    { 0.16078400000000001,    0.33725500000000003,    0.54117599999999999  },
+    /*  6 */    { 0.20000000000000001,    0.39607799999999999,    0.56862699999999999  },
+    /*  7 */    { 0.23921600000000001,    0.45490199999999997,    0.59999999999999998  },
+    /*  8 */    { 0.286275,               0.52156899999999995,    0.65098              },
+    /*  9 */    { 0.33725500000000003,    0.59215700000000004,    0.70196099999999995  },
+    /* 10 */    { 0.388235,               0.65490199999999998,    0.74902000000000002  },
+    /* 11 */    { 0.466667,               0.73725499999999999,    0.819608             },
+    /* 12 */    { 0.57254899999999997,    0.819608,               0.87843099999999996  },
+    /* 13 */    { 0.65490199999999998,    0.86666699999999997,    0.90980399999999995  },
+    /* 14 */    { 0.75294099999999997,    0.91764699999999999,    0.94117600000000001  },
+    /* 15 */    { 0.82352899999999996,    0.95686300000000002,    0.96862700000000002  },
+    ///* 15 */    { 1.0,                    1.0,                    1.0                  },
+    /* 16 */    { 0.98823499999999997,    0.96078399999999997,    0.90196100000000001  },
+    ///* 16 */    { 1.0,                    1.0,                    1.0                  },
+
+    ///* 17 */    { 1.0,                    1.0,                    1.0                  },
+    /* 17 */    { 0.94117600000000001,    0.98431400000000002,    0.98823499999999997  },
+    ///* 18 */    { 1.0,                    1.0,                    1.0                  },
+    /* 18 */    { 0.98823499999999997,    0.94509799999999999,    0.85097999999999996  },
+    ///* 19 */    { 1.0,                    1.0,                    1.0                  },
+    /* 19 */    { 0.98039200000000004,    0.89803900000000003,    0.78431399999999996  },
+    /* 20 */    { 0.96862700000000002,    0.83529399999999998,    0.69803899999999997  },
+    /* 21 */    { 0.94901999999999997,    0.73333300000000001,    0.58823499999999995  },
+    /* 22 */    { 0.92941200000000002,    0.65098,                0.50980400000000003  },
+    /* 23 */    { 0.90980399999999995,    0.56470600000000004,    0.43529400000000001  },
+    /* 24 */    { 0.87843099999999996,    0.45882400000000001,    0.352941             },
+    /* 25 */    { 0.83921599999999996,    0.388235,               0.286275             },
+    /* 26 */    { 0.76078400000000002,    0.29411799999999999,    0.21176500000000001  },
+    /* 27 */    { 0.70196099999999995,    0.21176500000000001,    0.168627             },
+    /* 28 */    { 0.65098,                0.156863,               0.129412             },
+    /* 29 */    { 0.59999999999999998,    0.094117999999999993,   0.094117999999999993 },
+    /* 30 */    { 0.54901999999999995,    0.066667000000000004,   0.098039000000000001 },
+    /* 31 */    { 0.50196099999999999,    0.050979999999999998,   0.12548999999999999  },
+    /* 32 */    { 0.45097999999999999,    0.054901999999999999,   0.17254900000000001  },
+    /* 33 */    { 0.40000000000000002,    0.054901999999999999,   0.19215699999999999  },
+    /* 34 */    { 0.34902,                0.070587999999999998,   0.21176500000000001  },
+                { 0.34902,                0.070587999999999998,   0.21176500000000001  } };
+    
+    if( value < min )
+        value = 0.0;
+    else if ( value > max )
+        value = 1.0;
+    else
+        value = ( value - min ) / ( max - min );
+
+    unsigned int idx           = value * 34;
+    double       interpolation = value * 34.0 - double( idx );
+
+    rgbColor color;
+
+    color.r = ( ( 1.0 - interpolation ) * colorMap[idx  ][0]
+              +         interpolation   * colorMap[idx+1][0] ) * 200.0 * 1.2;
+
+    color.g = ( ( 1.0 - interpolation ) * colorMap[idx  ][1]
+              +         interpolation   * colorMap[idx+1][1] ) * 197.0 * 1.2;
+
+    color.b = ( ( 1.0 - interpolation ) * colorMap[idx  ][2]
+              +         interpolation   * colorMap[idx+1][2] ) * 189.0 * 1.2;
+
+    return color;
+}
+
+void writePNG( vtkDataObject * inputData, int nx, int ny, double L, double H, std::string filename )
+{
+    vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
+    image->SetDimensions( nx, ny, 1 );
+    image->SetSpacing( L / ( nx - 1 ), H / ( ny - 1 ), 0 );
+
+    vtkSmartPointer<vtkResampleWithDataSet> resample = vtkSmartPointer<vtkResampleWithDataSet>::New();
+    resample->SetSourceData( inputData );
+    resample->SetInputData( image );
+    resample->Update();
+
+    vtkSmartPointer<vtkImageData> image2 = (vtkImageData*) resample->GetOutput();
+
+    image2->GetPointData()->SetScalars( image2->GetPointData()->GetArray( 0 ) );
+
+    vtkSmartPointer<vtkPNGWriter> writerPNG = vtkSmartPointer<vtkPNGWriter>::New();
+    writerPNG->SetFileName( ( filename + ".png" ).c_str() );
+    writerPNG->SetInputData( image2 );
+    writerPNG->Write();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void writeVtkXML(std::shared_ptr<DataBase> dataBase, 
+                 Parameters parameters, 
+                 int mode, 
+                 std::string filename)
+{
+    std::cout << "Write " << filename << ".vtu" << " ... ";
+
+    vtkGridPtr grid = getVtkUnstructuredOctGrid(dataBase);
+
+    addBaseData( grid, dataBase, parameters );
+
+    writeVtkUnstructuredGrid( grid, vtkXMLWriter::Binary, filename );
+
+    std::cout << "done!"<< std::endl;
+}
+
+void mapFlowField(std::shared_ptr<DataBase> base, std::shared_ptr<DataBase> target)
+{
+    vtkGridPtr gridBase   = getVtkUnstructuredOctGrid(base,   true);
+    vtkGridPtr gridTarget = getVtkUnstructuredOctGrid(target, true);
+
+    //////////////////////////////////////////////////////////////////////////
+
+    vtkSmartPointer<vtkDoubleArray> data = vtkSmartPointer<vtkDoubleArray>::New();
+            
+    data->SetNumberOfComponents( 4 );
+
+    data->SetName( "Cons" );
+
+    for( uint cellIdx = 0; cellIdx < base->numberOfCells; cellIdx++ ){
+
+        if( base->isGhostCell( cellIdx ) ) continue;
+                    
+        ConservedVariables cons;
+
+        cons.rho  = base->dataHost[ RHO__(cellIdx, base->numberOfCells) ];
+        cons.rhoU = base->dataHost[ RHO_U(cellIdx, base->numberOfCells) ];
+        cons.rhoV = base->dataHost[ RHO_V(cellIdx, base->numberOfCells) ];
+        cons.rhoW = base->dataHost[ RHO_W(cellIdx, base->numberOfCells) ];
+        cons.rhoE = base->dataHost[ RHO_E(cellIdx, base->numberOfCells) ];
+        data->InsertNextTuple4( cons.rho, cons.rhoU, cons.rhoV, cons.rhoE );
+    }
+
+    gridBase->GetCellData()->AddArray( data );
+        
+#ifdef USE_PASSIVE_SCALAR
+
+    vtkSmartPointer<vtkDoubleArray> dataS = vtkSmartPointer<vtkDoubleArray>::New();
+            
+    dataS->SetNumberOfComponents( 1 );
+
+    dataS->SetName( "rhoS" );
+
+    for( uint cellIdx = 0; cellIdx < base->numberOfCells; cellIdx++ ){
+
+        if( base->isGhostCell( cellIdx ) ) continue;
+        
+        ;
+        dataS->InsertNextTuple1( base->dataHost[ RHO_S(cellIdx, base->numberOfCells) ] );
+    }
+
+    gridBase->GetCellData()->AddArray( dataS );
+    
+#endif // USE_PASSIVE_SCALAR
+
+    //////////////////////////////////////////////////////////////////////////
+
+    vtkSmartPointer<vtkCellDataToPointData> cellDataToPointDataBase = vtkSmartPointer<vtkCellDataToPointData>::New();
+    cellDataToPointDataBase->SetInputData( gridBase );
+    cellDataToPointDataBase->Update();
+
+    vtkSmartPointer<vtkGeometryFilter> gridToPolyDataBase = vtkSmartPointer<vtkGeometryFilter>::New();
+    gridToPolyDataBase->SetInputConnection( cellDataToPointDataBase->GetOutputPort() );
+    gridToPolyDataBase->Update();
+
+    vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
+    cleanPolyData->SetInputConnection( gridToPolyDataBase->GetOutputPort() );
+    cleanPolyData->Update();
+
+    vtkSmartPointer<vtkResampleWithDataSet> resampleWithDataSet = vtkSmartPointer<vtkResampleWithDataSet>::New();
+    resampleWithDataSet->SetSourceConnection( cleanPolyData->GetOutputPort() );
+    resampleWithDataSet->SetInputData(  gridTarget );
+    resampleWithDataSet->Update();
+
+    vtkSmartPointer<vtkPointDataToCellData> pointDataToCellDataTarget = vtkSmartPointer<vtkPointDataToCellData>::New();
+    pointDataToCellDataTarget->SetInputConnection( resampleWithDataSet->GetOutputPort() );
+    pointDataToCellDataTarget->Update();
+
+    gridTarget = (vtkUnstructuredGrid*) pointDataToCellDataTarget->GetOutput();
+
+    //////////////////////////////////////////////////////////////////////////
+
+    for( uint cellIdx = 0, gridCellIdx = 0; cellIdx < target->numberOfCells; cellIdx++ ){
+
+        if( target->isGhostCell( cellIdx ) ) continue;
+
+        double* cons = gridTarget->GetCellData()->GetArray(1)->GetTuple4(gridCellIdx);
+
+        target->dataHost[ RHO__(cellIdx, target->numberOfCells) ] = cons[0];
+        target->dataHost[ RHO_U(cellIdx, target->numberOfCells) ] = cons[1];
+        target->dataHost[ RHO_V(cellIdx, target->numberOfCells) ] = cons[2];
+        target->dataHost[ RHO_E(cellIdx, target->numberOfCells) ] = cons[3];
+
+#ifdef USE_PASSIVE_SCALAR
+
+        double  rhoS = gridTarget->GetCellData()->GetArray(2)->GetTuple1(gridCellIdx);
+
+        target->dataHost[ RHO_S(cellIdx, target->numberOfCells) ] = rhoS;
+
+#endif // USE_PASSIVE_SCALAR
+
+        gridCellIdx++;
+    }
+}
\ No newline at end of file
diff --git a/src/GksVtkAdapter/VTKAdapter.h b/src/GksVtkAdapter/VTKAdapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..676df2b15127a60a67a9f42789bd9497455ad403
--- /dev/null
+++ b/src/GksVtkAdapter/VTKAdapter.h
@@ -0,0 +1,69 @@
+#ifndef VTKAdapter_H
+#define VTKAdapter_H
+
+#include <vtkSmartPointer.h>
+#include <vtkVersion.h>
+ 
+#include <vtkPoints.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkDataObject.h>
+
+
+#include <vtkIdList.h>
+
+#include <vtkIntArray.h>
+#include <vtkDoubleArray.h>
+
+#include <vtkXMLUnstructuredGridWriter.h>
+
+#include <memory>
+#include <functional>
+#include <string>
+
+#include "Core/PointerDefinitions.h"
+
+#include "VirtualFluidsDefinitions.h"
+
+#include "DataBase/DataBase.h"
+#include "Parameters/Parameters.h"
+
+typedef vtkSmartPointer<vtkUnstructuredGrid>          vtkGridPtr;
+typedef vtkSmartPointer<vtkPoints>                    vtkPointsPtr;
+typedef vtkSmartPointer<vtkIdList>                    vtkIdListPtr;
+typedef vtkSmartPointer<vtkIntArray>                  vtkIntArrayPtr;
+typedef vtkSmartPointer<vtkDoubleArray>               vtkDoubleArrayPtr;
+typedef vtkSmartPointer<vtkXMLUnstructuredGridWriter> vtkWriterPtr;
+
+struct rgbColor
+{
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+};
+
+vtkGridPtr VF_PUBLIC getVtkUnstructuredOctGrid( SPtr<DataBase> dataBase, bool excludeGhostCells = false );
+
+void VF_PUBLIC addScalarIntCellData( vtkGridPtr grid, 
+                                     uint numberOfCells, 
+                                     std::string name, 
+                                     std::function<int(uint)> getData );
+
+void VF_PUBLIC addScalarRealCellData( vtkGridPtr grid, 
+                                      uint numberOfCells, 
+                                      std::string name, 
+                                      std::function<real(uint)> getData );
+
+void VF_PUBLIC addVectorCellData( vtkGridPtr grid, 
+                                  uint numberOfCells, 
+                                  std::string name, 
+                                  std::function<Vec3(uint)> getData );
+
+void VF_PUBLIC addBaseData( vtkGridPtr grid, SPtr<DataBase> dataBase, Parameters parameters );
+
+void VF_PUBLIC writeVtkUnstructuredGrid( vtkGridPtr grid, int mode, std::string filename );
+
+rgbColor VF_PUBLIC colorMapCoolToWarmExtended( double value, double min, double max );
+
+void VF_PUBLIC writePNG( vtkDataObject* inputData, int nx, int ny, double L, double H, std::string filename );
+
+#endif
\ No newline at end of file
diff --git a/src/GksVtkAdapter/VTKInterface.h b/src/GksVtkAdapter/VTKInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..22984aec1eb4811c93edd2eae8f4ecfbd05949d7
--- /dev/null
+++ b/src/GksVtkAdapter/VTKInterface.h
@@ -0,0 +1,17 @@
+#ifndef VTKInterface_H
+#define VTKInterface_H
+
+#include "GksGpu/DataBase/DataBase.h"
+#include "GksGpu/Parameters/Parameters.h"
+
+#include "VirtualFluidsDefinitions.h"
+
+void VF_PUBLIC writeVtkXML(std::shared_ptr<DataBase> dataBase, 
+                           Parameters parameters, 
+                           int mode, 
+                           std::string filename);
+
+
+void VF_PUBLIC mapFlowField( std::shared_ptr<DataBase> base, std::shared_ptr<DataBase> target );
+
+#endif
\ No newline at end of file
diff --git a/src/GksVtkAdapter/package.include b/src/GksVtkAdapter/package.include
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/targets/apps/GKS/gksTest/3rdPartyLinking.cmake b/targets/apps/GKS/gksTest/3rdPartyLinking.cmake
index 6dd6ba1bc73e73dfbf01a3cc36aaeb3664e1c04c..72c7afc6076b832263506ab9ce777925cfcc6a66 100644
--- a/targets/apps/GKS/gksTest/3rdPartyLinking.cmake
+++ b/targets/apps/GKS/gksTest/3rdPartyLinking.cmake
@@ -2,12 +2,10 @@ include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/MPI/Link.cmake)
 linkMPI(${targetName})
 include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Cuda/Link.cmake)
 linkCuda(${targetName})
-include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Boost/Link.cmake)
-linkBoost(${targetName} "serialization")
-include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Metis/Link.cmake)
-linkMetis(${targetName})
+#include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Metis/Link.cmake)
+#linkMetis(${targetName})
 
-if(HULC.BUILD_JSONCPP)
-  include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/JsonCpp/Link.cmake)
-  linkJsonCpp(${targetName})
-endif()
\ No newline at end of file
+#if(HULC.BUILD_JSONCPP)
+#  include (${CMAKE_SOUR#CE_DIR}/${cmakeMacroPath}/JsonCpp/Link.cmake)
+#  linkJsonCpp(${targetName})
+#endif()
diff --git a/targets/apps/GKS/gksTest/CMakeLists.txt b/targets/apps/GKS/gksTest/CMakeLists.txt
index bf204134ec8687a5a277f5af89fe847d922ada5b..d20662f5a73bba566cf07320ec6d05c48c3586ea 100644
--- a/targets/apps/GKS/gksTest/CMakeLists.txt
+++ b/targets/apps/GKS/gksTest/CMakeLists.txt
@@ -1,10 +1,12 @@
-setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR}) 
+setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR})
 
 set(linkDirectories "")
-set(libsToLink GridGenerator GksMeshAdapter)
+set(libsToLink GridGenerator GksMeshAdapter GksVtkAdapter GksGpu)
 set(includeDirectories "${CMAKE_SOURCE_DIR}/src"
                        "${CMAKE_SOURCE_DIR}/src/GridGenerator"
-                       "${CMAKE_SOURCE_DIR}/src/GksMeshAdapter")
+                       "${CMAKE_SOURCE_DIR}/src/GksMeshAdapter"
+                       "${CMAKE_SOURCE_DIR}/src/GksVtkAdapter"
+                       "${CMAKE_SOURCE_DIR}/src/GksGpu")
 
 #glob files and save in MY_SRCS
 include(CMakePackage.cmake)
@@ -13,4 +15,4 @@ buildExe(${targetName} "${MY_SRCS}" "${linkDirectories}" "${libsToLink}" "${incl
 groupTarget(${targetName} ${gksAppFolder})
 
 # Specify the linking to 3rdParty libs
-include(3rdPartyLinking.cmake)
\ No newline at end of file
+include(3rdPartyLinking.cmake)
diff --git a/targets/apps/GKS/gksTest/main.cpp b/targets/apps/GKS/gksTest/main.cpp
index 7907c851f8c9323dde9918979ead2b69585bedf0..5be8c4fded8e7975fd10344764dfa12a4e0201d0 100644
--- a/targets/apps/GKS/gksTest/main.cpp
+++ b/targets/apps/GKS/gksTest/main.cpp
@@ -1,11 +1,12 @@
 //#define MPI_LOGGING
 
+#define _USE_MATH_DEFINES
+#include <math.h>
 #include <string>
 #include <iostream>
 #include <exception>
 #include <fstream>
-#define _USE_MATH_DEFINES
-#include <math.h>
+#include <memory>
 
 #include "core/Logger/Logger.h"
 
@@ -19,7 +20,13 @@
 
 #include "GksMeshAdapter/GksMeshAdapter.h"
 
-void gksTest()
+#include "GksVtkAdapter/VTKInterface.h"
+
+#include "GksGpu/DataBase/DataBase.h"
+#include "GksGpu/Parameters/Parameters.h"
+#include "GksGpu/Initializer/Initializer.h"
+
+void gksTest( std::string path )
 {
     auto gridFactory = GridFactory::make();
     gridFactory->setGridStrategy(Device::CPU);
@@ -36,14 +43,14 @@ void gksTest()
 
     Cuboid cube(-1.0, -1.0, 0.45, 1.0, 1.0, 0.55);
 
-    gridBuilder->setNumberOfLayers(10,8);
-    gridBuilder->addGrid( &cube, 1);
+    //gridBuilder->setNumberOfLayers(10,8);
+    //gridBuilder->addGrid( &cube, 1);
 
     gridBuilder->setPeriodicBoundaryCondition(false, false, false);
 
     gridBuilder->buildGrids(GKS, false);
 
-    gridBuilder->writeGridsToVtk("F:/Work/Computations/gridGenerator/grid/Grid_lev_");
+    gridBuilder->writeGridsToVtk(path + "grid/Grid_lev_");
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -71,13 +78,37 @@ void gksTest()
 
     meshAdapter.generateInterfaceConnectivity();
 
-    meshAdapter.writeMeshVTK( "F:/Work/Computations/gridGenerator/grid/Mesh.vtk" );
+    //meshAdapter.writeMeshVTK( path + "grid/Mesh.vtk" );
+
+    //meshAdapter.writeMeshFaceVTK( path + "grid/MeshFaces.vtk" );
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    Parameters parameters;
+    
+    auto dataBase = std::make_shared<DataBase>( "GPU" );
+    dataBase->setMesh( meshAdapter );
+
+    Initializer::interpret(dataBase, [&] ( Vec3 cellCenter ) -> ConservedVariables {
+        
+        real radius = cellCenter.length();
+
+        return toConservedVariables( PrimitiveVariables( 1.0, 0.0, 0.0, 0.0, 1.0, radius ), parameters.K );
+
+    });
+
+    dataBase->copyDataHostToDevice();
+
+    dataBase->copyDataDeviceToHost();
+
+    writeVtkXML( dataBase, parameters, 0, path + "grid/Test" );
+
 
-    meshAdapter.writeMeshFaceVTK( "F:/Work/Computations/gridGenerator/grid/MeshFaces.vtk" );
 }
 
 int main( int argc, char* argv[])
 {
+    std::string path( "F:/Work/Computations/gridGenerator/" );
 
     logging::Logger::addStream(&std::cout);
     logging::Logger::setDebugLevel(logging::Logger::Level::INFO_LOW);
@@ -85,7 +116,7 @@ int main( int argc, char* argv[])
     
     try
     {
-        gksTest();
+        gksTest( path );
     }
     catch (const std::exception& e)
     {     
diff --git a/targets/libs/GksGpu/3rdPartyLinking.cmake b/targets/libs/GksGpu/3rdPartyLinking.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..838d1037e56d1a5448881d07f5ff60568e3df0fb
--- /dev/null
+++ b/targets/libs/GksGpu/3rdPartyLinking.cmake
@@ -0,0 +1,6 @@
+include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Cuda/Link.cmake)
+linkCuda(${targetName})
+include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/MPI/Link.cmake)
+linkMPI(${targetName})
+#include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Boost/Link.cmake)
+#linkBoost(${targetName} "serialization")
diff --git a/targets/libs/GksGpu/CMakeLists.txt b/targets/libs/GksGpu/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..477314aa7f7c897f1eb97514e4066a0d80f7f592
--- /dev/null
+++ b/targets/libs/GksGpu/CMakeLists.txt
@@ -0,0 +1,18 @@
+setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR}) 
+
+set(linkDirectories "")
+set(libsToLink GksMeshAdapter Core)
+
+set(includeDirectories ${CMAKE_SOURCE_DIR}/src/${targetName}
+                       ${CMAKE_SOURCE_DIR}/src
+                       ${CMAKE_SOURCE_DIR}/src/GksMeshAdapter
+                       ${CMAKE_SOURCE_DIR}/src/Core )
+
+#glob files and save in MY_SRCS
+include(CMakePackage.cmake)
+
+buildLib(${targetName} "${MY_SRCS}" "${linkDirectories}" "${libsToLink}" "${includeDirectories}")
+groupTarget(${targetName} ${gksLibraryFolder})
+
+#Specify the linking to 3rdParty libs
+include(3rdPartyLinking.cmake)
diff --git a/targets/libs/GksGpu/CMakePackage.cmake b/targets/libs/GksGpu/CMakePackage.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7ec316fe087d1886a7dbdbfb7298bae1fc7ddedd
--- /dev/null
+++ b/targets/libs/GksGpu/CMakePackage.cmake
@@ -0,0 +1,8 @@
+#FILE ENDINGS
+resetFileEndingsToCollect()
+addCAndCPPFileTypes()
+
+#GLOB SOURCE FILES IN MY_SRCS
+unset(MY_SRCS)
+includeRecursiveAllFilesFrom(${targetName} ${CMAKE_CURRENT_LIST_DIR})
+includeRecursiveProductionFilesFrom(${targetName} ${CMAKE_SOURCE_DIR}/src/${targetName})
\ No newline at end of file
diff --git a/targets/libs/GksMeshAdapter/3rdPartyLinking.cmake b/targets/libs/GksMeshAdapter/3rdPartyLinking.cmake
index 6feb9029ed32c85c31304372e4be8554464f5e7c..838d1037e56d1a5448881d07f5ff60568e3df0fb 100644
--- a/targets/libs/GksMeshAdapter/3rdPartyLinking.cmake
+++ b/targets/libs/GksMeshAdapter/3rdPartyLinking.cmake
@@ -2,5 +2,5 @@ include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Cuda/Link.cmake)
 linkCuda(${targetName})
 include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/MPI/Link.cmake)
 linkMPI(${targetName})
-include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Boost/Link.cmake)
-linkBoost(${targetName} "serialization")
\ No newline at end of file
+#include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Boost/Link.cmake)
+#linkBoost(${targetName} "serialization")
diff --git a/targets/libs/GksVtkAdapter/3rdPartyLinking.cmake b/targets/libs/GksVtkAdapter/3rdPartyLinking.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..72a16234916a157280b9441b38598c4cc1df1520
--- /dev/null
+++ b/targets/libs/GksVtkAdapter/3rdPartyLinking.cmake
@@ -0,0 +1,2 @@
+include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/VTK/Link.cmake)
+linkVTK(${targetName})
diff --git a/targets/libs/GksVtkAdapter/CMakeLists.txt b/targets/libs/GksVtkAdapter/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..41d654e3a4471ca6d8d46edcb6c1a25d4d00544b
--- /dev/null
+++ b/targets/libs/GksVtkAdapter/CMakeLists.txt
@@ -0,0 +1,18 @@
+setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR})
+
+set(linkDirectories "")
+set(libsToLink GksGpu Core)
+
+set(includeDirectories ${CMAKE_SOURCE_DIR}/src/${targetName}
+                       ${CMAKE_SOURCE_DIR}/src
+                       ${CMAKE_SOURCE_DIR}/src/GksGpu
+                       ${CMAKE_SOURCE_DIR}/src/Core )
+
+#glob files and save in MY_SRCS
+include(CMakePackage.cmake)
+
+buildLib(${targetName} "${MY_SRCS}" "${linkDirectories}" "${libsToLink}" "${includeDirectories}")
+groupTarget(${targetName} ${gksLibraryFolder})
+
+#Specify the linking to 3rdParty libs
+include(3rdPartyLinking.cmake)
diff --git a/targets/libs/GksVtkAdapter/CMakePackage.cmake b/targets/libs/GksVtkAdapter/CMakePackage.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7ec316fe087d1886a7dbdbfb7298bae1fc7ddedd
--- /dev/null
+++ b/targets/libs/GksVtkAdapter/CMakePackage.cmake
@@ -0,0 +1,8 @@
+#FILE ENDINGS
+resetFileEndingsToCollect()
+addCAndCPPFileTypes()
+
+#GLOB SOURCE FILES IN MY_SRCS
+unset(MY_SRCS)
+includeRecursiveAllFilesFrom(${targetName} ${CMAKE_CURRENT_LIST_DIR})
+includeRecursiveProductionFilesFrom(${targetName} ${CMAKE_SOURCE_DIR}/src/${targetName})
\ No newline at end of file
diff --git a/targets/libs/GridGenerator/3rdPartyLinking.cmake b/targets/libs/GridGenerator/3rdPartyLinking.cmake
index 376fc4ee0c8ba63d5ddcb1a42bd36c5b18e66c92..4058258a4aedac7a358ea81f9ec3f8ad8345e09c 100644
--- a/targets/libs/GridGenerator/3rdPartyLinking.cmake
+++ b/targets/libs/GridGenerator/3rdPartyLinking.cmake
@@ -7,4 +7,4 @@ linkBoost(${targetName} "serialization")
 include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/Metis/Link.cmake)
 linkMetis(${targetName})
 include (${CMAKE_SOURCE_DIR}/${cmakeMacroPath}/OpenMP/Link.cmake)
-linkOpenMP(${targetName})
\ No newline at end of file
+linkOpenMP(${targetName})
diff --git a/targets/libs/GridGenerator/CMakeLists.txt b/targets/libs/GridGenerator/CMakeLists.txt
index 3d979614111a89fd514f3033e1b5cbe00dc8c58e..1ab0b7572c4dcd8c1bc40e63ac9882bc97dadd77 100644
--- a/targets/libs/GridGenerator/CMakeLists.txt
+++ b/targets/libs/GridGenerator/CMakeLists.txt
@@ -1,7 +1,8 @@
-setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR}) 
+setTargetNameToFolderName(${CMAKE_CURRENT_LIST_DIR})
 
 set(linkDirectories "")
 set(libsToLink VirtualFluidsBasics Core)
+
 set(includeDirectories ${CMAKE_SOURCE_DIR}/src/${targetName}
                        ${CMAKE_SOURCE_DIR}/src
                        ${CMAKE_SOURCE_DIR}/src/VirtualFluidsBasics
@@ -14,4 +15,4 @@ buildLib(${targetName} "${MY_SRCS}" "${linkDirectories}" "${libsToLink}" "${incl
 groupTarget(${targetName} ${libraryFolder})
 
 # Specify the linking to 3rdParty libs
-include(3rdPartyLinking.cmake)
\ No newline at end of file
+include(3rdPartyLinking.cmake)