From e976b6e4f07f4f4e3585e2e53d9440ce2bb77293 Mon Sep 17 00:00:00 2001
From: Soeren Peters <peters@irmb.tu-bs.de>
Date: Tue, 16 Jan 2018 17:31:13 +0100
Subject: [PATCH] - creates grid strategy to allocate on cpu/gpus and invoke
 meshing and initalization

---
 src/GridGenerator/global.h                    |    1 +
 src/GridGenerator/grid/Grid.cu                |  138 ++-
 src/GridGenerator/grid/Grid.cuh               |   21 +-
 .../grid/GridBuilder/GridBuilder.h            |    3 +-
 .../grid/GridBuilder/LevelGridBuilder.cpp     |   83 +-
 .../grid/GridBuilder/LevelGridBuilder.h       |    6 +-
 .../grid/GridBuilder/ParallelGridBuilder.cpp  | 1082 ++++++++---------
 .../grid/GridBuilder/ParallelGridBuilder.h    |  200 +--
 .../GridCpuStrategy/GridCpuStrategy.cpp       |   93 ++
 .../GridCpuStrategy/GridCpuStrategy.h         |   37 +
 .../GridCpuStrategy/GridCpuStrategyTest.cpp}  |    0
 .../GridCpuStrategy}/package.include          |    0
 .../GridGpuStrategy/GridGpuStrategy.cpp       |  247 ++++
 .../GridGpuStrategy/GridGpuStrategy.h         |   53 +
 .../GridGpuStrategy/GridGpuStrategyTest.cpp}  |    0
 .../GridGpuStrategy}/package.include          |    0
 .../grid/GridStrategy/GridStrategy.h          |   30 +
 .../package.include                           |    0
 src/GridGenerator/grid/GridTest.cpp           |   27 +-
 .../grid/GridWrapper/GridWrapper.cpp          |    0
 .../grid/GridWrapper/GridWrapper.h            |   30 -
 .../GridWrapperCPU/GridWrapperCPU.h           |   42 -
 .../GridWrapperGPU/GridWrapperGPU.cpp         |  264 ----
 .../GridWrapperGPU/GridWrapperGPU.h           |   47 -
 .../grid/kernel/runGridKernelGPU.cu           |    2 +-
 .../SimulationFileWriter.cpp                  |    3 +-
 src/core/PointerDefinitions.h                 |    3 +
 targets/apps/HULC/main.cpp                    |   36 +-
 28 files changed, 1291 insertions(+), 1157 deletions(-)
 create mode 100644 src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
 create mode 100644 src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
 rename src/GridGenerator/grid/{GridWrapper/GridWrapperCPU/GridWrapperCPUTest.cpp => GridStrategy/GridCpuStrategy/GridCpuStrategyTest.cpp} (100%)
 rename src/GridGenerator/grid/{GridWrapper/GridWrapperCPU => GridStrategy/GridCpuStrategy}/package.include (100%)
 create mode 100644 src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
 create mode 100644 src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h
 rename src/GridGenerator/grid/{GridWrapper/GridWrapperGPU/GridWrapperGPUTest.cpp => GridStrategy/GridGpuStrategy/GridGpuStrategyTest.cpp} (100%)
 rename src/GridGenerator/grid/{GridWrapper/GridWrapperGPU => GridStrategy/GridGpuStrategy}/package.include (100%)
 create mode 100644 src/GridGenerator/grid/GridStrategy/GridStrategy.h
 rename src/GridGenerator/grid/{GridWrapper => GridStrategy}/package.include (100%)
 delete mode 100644 src/GridGenerator/grid/GridWrapper/GridWrapper.cpp
 delete mode 100644 src/GridGenerator/grid/GridWrapper/GridWrapper.h
 delete mode 100644 src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h
 delete mode 100644 src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.cpp
 delete mode 100644 src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h

diff --git a/src/GridGenerator/global.h b/src/GridGenerator/global.h
index cd49c7f7e..e8f34934f 100644
--- a/src/GridGenerator/global.h
+++ b/src/GridGenerator/global.h
@@ -29,5 +29,6 @@
 
 #include <GridGenerator/utilities/cuda/cudaDefines.h>
 #include "VirtualFluidsDefinitions.h"
+#include "core/PointerDefinitions.h"
 
 #endif // !global_h
diff --git a/src/GridGenerator/grid/Grid.cu b/src/GridGenerator/grid/Grid.cu
index 41debd4dc..a0cf27ae0 100644
--- a/src/GridGenerator/grid/Grid.cu
+++ b/src/GridGenerator/grid/Grid.cu
@@ -2,6 +2,8 @@
 
 #include "GridGenerator/global.h"
 #include <stdio.h>
+#include <time.h>
+
 #include <sstream>
 #include <algorithm>
 
@@ -14,9 +16,14 @@
 #include <GridGenerator/grid/NodeValues.h>
 #include <GridGenerator/grid/distributions/Distribution.h>
 
+#include <GridGenerator/grid/GridStrategy/GridStrategy.h>
+#include <utilities/logger/Logger.h>
+
+
 __constant__ int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
-HOSTDEVICE Grid::Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, Distribution &d) : sX(startX), sY(startY), sZ(startZ), eX(endX), eY(endY), eZ(endZ), delta(delta), d(d)
+HOST Grid::Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution &d) 
+: sX(startX), sY(startY), sZ(startZ), eX(endX), eY(endY), eZ(endZ), delta(delta), gridStrategy(gridStrategy), d(d)
 {
     real length = endX - startX;
     real width = endY - startY;
@@ -28,26 +35,58 @@ HOSTDEVICE Grid::Grid(real startX, real startY, real startZ, real endX, real end
 
     this->size = nx * ny * nz;
     this->reducedSize = size;
+}
+
+HOST SPtr<Grid> Grid::getNewInstance(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution &d)
+{
+    SPtr<Grid> grid(new Grid(startX, startY, startZ, endX, endY, endZ, delta, gridStrategy, d));
+
+    gridStrategy->allocateGridMemory(grid);
 
-    const unsigned long distributionSize = size * (d.dir_end + 1);
-    this->d.f = new real[distributionSize](); // automatic initialized with zeros
-    this->field = new char[this->size];
+    *logging::out << logging::Logger::LOW << "-------------------------------------------\n";
+    *logging::out << logging::Logger::LOW << "Initial field with fluid. \n";
+    *logging::out << logging::Logger::LOW << "-------------------------------------------\n";
 
-    this->neighborIndexX = new int[this->size];
-    this->neighborIndexY = new int[this->size];
-    this->neighborIndexZ = new int[this->size];
+    time_t begin = clock();
 
-    this->matrixIndex = new uint[this->size];
+    gridStrategy->initalNodes(grid);
+
+    time_t end = clock();
+    real time = (real)(real(end - begin) / CLOCKS_PER_SEC);
+    *logging::out << logging::Logger::INTERMEDIATE << "Time initial field: " + SSTR(time / 1000) + "sec\n";
+    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
+
+    return grid;
 }
 
-HOSTDEVICE Grid::Grid(){};
-HOSTDEVICE Grid::Grid(char *field, int startX, int startY, int startZ, int nx, int ny, int nz, Distribution &d)
-    : field(field), startX(startX), startY(startY), startZ(startZ), nx(nx), ny(ny), nz(nz), d(d)
+HOST Grid::Grid(){};
+HOST Grid::Grid(char *field, int startX, int startY, int startZ, int eX, int eY, int eZ, Distribution &d)
+    : field(field), sX(startX), sY(startY), sZ(startZ), eX(eX), eY(eY), eZ(eZ), d(d)
 {
-    this->size = nx * ny * nz;
+    nx = eX;
+    ny = eY;
+    nz = eZ;
+    this->size = eX * eY * eZ;
     this->reducedSize = size;
 }
 
+HOST void Grid::mesh(Geometry &geometry)
+{
+    clock_t begin = clock();
+
+    gridStrategy->mesh(shared_from_this(), geometry);
+
+    clock_t end = clock();
+    float time = (real)(real(end - begin) / CLOCKS_PER_SEC);
+
+    *logging::out << logging::Logger::INTERMEDIATE << "time grid generation: " + SSTR(time) + "s\n";
+}
+
+HOST void Grid::freeMemory()
+{
+    gridStrategy->freeMemory(shared_from_this());
+}
+
 HOSTDEVICE bool Grid::isFluid(int index) const
 {
     return field[index] == FLUID;
@@ -95,10 +134,10 @@ HOSTDEVICE int Grid::transCoordToIndex(const real &x, const real &y, const real
 
 HOSTDEVICE int Grid::transCoordToIndex(const Vertex &v) const
 {
-//#ifdef DEBUG
-//	if (isOutOfRange(v))
-//	{ printf("Function: transCoordToIndex. Coordinates are out of range and cannot calculate the index. Exit Program!\n");/* exit(1);*/ };
-//#endif
+#ifdef DEBUG
+	if (isOutOfRange(v))
+	{ printf("Function: transCoordToIndex. Coordinates are out of range and cannot calculate the index. Exit Program!\n");/* exit(1);*/ };
+#endif
     int x = (int)((v.x - sX) / delta);
     int y = (int)((v.y - sY) / delta);
     int z = (int)((v.z - sZ) / delta);
@@ -108,19 +147,19 @@ HOSTDEVICE int Grid::transCoordToIndex(const Vertex &v) const
 
 HOSTDEVICE void Grid::transIndexToCoords(const int index, real &x, real &y, real &z) const
 {
-//#ifdef DEBUG
-//	if (index < 0 || index >= (int)size)
-//	{
-//        printf("Function: transIndexToCoords. Grid Index: %d, size: %d. Exit Program!\n", index, size); /*exit(1);*/ 
-//    };
-//#endif
+#ifdef DEBUG
+	if (index < 0 || index >= (int)size)
+	{
+        printf("Function: transIndexToCoords. Grid Index: %d, size: %d. Exit Program!\n", index, size); /*exit(1);*/ 
+    };
+#endif
     x = index % nx;
     y = (index / nx) % ny;
     z = ((index / nx) / ny) % nz;
 
-    x = (x + sX) * delta;
-    y = (y + sY) * delta;
-    z = (z + sZ) * delta;
+    x = (x * delta) + sX;
+    y = (y * delta) + sY;
+    z = (z * delta) + sZ;
 }
 
 char* Grid::toString(const char* name) const
@@ -130,10 +169,9 @@ char* Grid::toString(const char* name) const
     return strdup(ss.str().c_str());
 }
 
-
 HOSTDEVICE void Grid::print() const
 {
-    printf("Dimension: (%d, %d, %d), size: %d, offset: (%d, %d, %d)\n", nx, ny, nz, size, startX, startY, startZ);
+    printf("min: (%d, %d, %d), max: (%d, %d, %d), size: %d, delta: %d\n", sX, sY, sZ, eX, eY, eZ, size, delta);
 }
 
 HOSTDEVICE void Grid::setDebugPoint(const Vertex &point, const int pointValue)
@@ -147,13 +185,9 @@ HOSTDEVICE void Grid::setDebugPoint(const Vertex &point, const int pointValue)
 
 HOSTDEVICE bool Grid::isOutOfRange(const Vertex &v) const
 {
-	int gridX = (int)v.x - startX;
-	int gridY = (int)v.y - startY;
-	int gridZ = (int)v.z - startZ;
-	return (gridX < 0 || gridY < 0 || gridZ < 0 || gridX >= (int)nx || gridY >= (int)ny || gridZ >= (int)nz);
+	return v.x < sX || v.y < sY || v.z < sZ || v.x > eX || v.y > eY || v.z > eZ;
 }
 
-
 HOSTDEVICE void Grid::meshTriangleExact(const Triangle &triangle)
 {
     BoundingBox<real> box = BoundingBox<real>::makeRealNodeBox(triangle, delta);
@@ -162,13 +196,13 @@ HOSTDEVICE void Grid::meshTriangleExact(const Triangle &triangle)
         for (real y = box.minY; y <= box.maxY; y += delta) {
             for (real z = box.minZ; z <= box.maxZ; z += delta) {
                 Vertex point(x, y, z);
-                //if (isOutOfRange(point))
-                //    continue;
+                if (isOutOfRange(point))
+                    continue;
                 const int value = triangle.isUnderFace(point);
                 setDebugPoint(point, value);
 
-                //if (value == Q)
-                //    calculateQs(point, triangle);
+                if (value == Q)
+                    calculateQs(point, triangle);
             }
         }
     }
@@ -199,22 +233,22 @@ HOSTDEVICE void Grid::meshTriangle(const Triangle &triangle)
 
 HOSTDEVICE void Grid::calculateQs(const Vertex &point, const Triangle &triangle)
 {
-	Vertex pointOnTriangle, dir;
+	Vertex pointOnTriangle, direction;
 	//VertexInteger solid_node;
-	real qVal;
-	int err;
+	real subdistance;
+	int error;
 	for (int i = d.dir_start; i <= d.dir_end; i++) {
 	#if defined(__CUDA_ARCH__)
-		dir = Vertex(DIRECTIONS[i][0], DIRECTIONS[i][1], DIRECTIONS[i][2]);
+        direction = Vertex(DIRECTIONS[i][0], DIRECTIONS[i][1], DIRECTIONS[i][2]);
 	#else
-		dir = Vertex((real)d.dirs[i * DIMENSION + 0], (real)d.dirs[i * DIMENSION + 1], (real)d.dirs[i * DIMENSION + 2]);
+        direction = Vertex((real)d.dirs[i * DIMENSION + 0], (real)d.dirs[i * DIMENSION + 1], (real)d.dirs[i * DIMENSION + 2]);
 	#endif
 
-		err = triangle.getTriangleIntersection(point, dir, pointOnTriangle, qVal);
+        error = triangle.getTriangleIntersection(point, direction, pointOnTriangle, subdistance);
 
-		if (err != 0 && qVal <= 1.0f) {
-			//solid_node = VertexInteger(actualPoint.x + dir.x, actualPoint.y + dir.y, actualPoint.z + dir.z);
-			d.f[i*size + transCoordToIndex(point)] = qVal;
+		if (error != 0 && subdistance <= 1.0f) {
+			//solid_node = VertexInteger(actualPoint.x + direction.x, actualPoint.y + direction.y, actualPoint.z + direction.z);
+			d.f[i*size + transCoordToIndex(point)] = subdistance;
 			//printf("Q%d %d: %2.8f \n", i, grid.transCoordToIndex(actualPoint), grid.d.f[index]);
 		}
 	}
@@ -277,7 +311,8 @@ HOSTDEVICE int Grid::getNeighborIndex(const int &nodeIndex, int &neighborIndex,
         neighborIndex--;
         //printf("here\n");
     }
-    if (neighborIndex >= 0) {
+    if (neighborIndex >= 0)
+    {
         real neighborX, neighborY, neighborZ;
         this->transIndexToCoords(this->matrixIndex[neighborIndex], neighborX, neighborY, neighborZ);
         while (!(neighborX == expectedX && neighborY == expectedY && neighborZ == expectedZ)) {
@@ -292,9 +327,7 @@ HOSTDEVICE int Grid::getNeighborIndex(const int &nodeIndex, int &neighborIndex,
         }
         return neighborIndex;
     }
-    else {
-        return -1;
-    }
+    return -1;
 }
 
 
@@ -324,12 +357,11 @@ HOST void Grid::removeInvalidNodes()
 
 HOSTDEVICE void Grid::getNeighborCoords(real &neighborX, real &neighborY, real &neighborZ, const real x, const real y, const real z) const
 {
-	neighborX = x + delta < nx ? x + delta : startX;
-	neighborY = y + delta < ny ? y + delta : startY;
-	neighborZ = z + delta < nz ? z + delta : startZ;
+	neighborX = x + delta < sX ? x + delta : sX;
+    neighborY = y + delta < sY ? y + delta : sY;
+    neighborZ = z + delta < sZ ? z + delta : sZ;
 }
 
-
 HOSTDEVICE bool Grid::isStopper(int index) const
 {
     return isSolid(index) && previousCellHasFluid(index);
diff --git a/src/GridGenerator/grid/Grid.cuh b/src/GridGenerator/grid/Grid.cuh
index 9e1d6cdc5..2f77b830f 100644
--- a/src/GridGenerator/grid/Grid.cuh
+++ b/src/GridGenerator/grid/Grid.cuh
@@ -4,20 +4,19 @@
 #include "GridGenerator/global.h"
 
 
-#include <stdio.h>
-#include <sstream>
-#include "cuda.h"
-#include "cuda_runtime.h"
-
 #include <GridGenerator/grid/distributions/Distribution.h>
 
+struct Geometry;
 struct Vertex;
 struct Triangle;
+class GridStrategy;
 
 extern CONSTANT int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
-struct VF_PUBLIC Grid 
+struct VF_PUBLIC Grid : enableSharedFromThis<Grid>
 {
+    SPtr<GridStrategy> gridStrategy;
+
     real sX = 0.0, sY = 0.0, sZ = 0.0;
     real eX, eY, eZ;
     real delta = 1.0;
@@ -32,9 +31,13 @@ struct VF_PUBLIC Grid
     unsigned int *matrixIndex;
     int reducedSize;
 
-    HOSTDEVICE Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, Distribution &d);
-	HOSTDEVICE Grid();
-	HOSTDEVICE Grid(char *field, int startX, int startY, int startZ, int nx, int ny, int nz, Distribution &d);
+    HOST Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, SPtr<GridStrategy> gridStrategy, Distribution &d);
+    HOST Grid();
+    HOST Grid(char *field, int startX, int startY, int startZ, int nx, int ny, int nz, Distribution &d);
+    static HOST SPtr<Grid> getNewInstance(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution &d);
+
+    HOST void mesh(Geometry &geometry);
+    HOST void freeMemory();
 
 	HOSTDEVICE bool isFluid(int index) const;
 	HOSTDEVICE bool isSolid(int index) const;
diff --git a/src/GridGenerator/grid/GridBuilder/GridBuilder.h b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
index 1ad018fe0..53af11d2c 100644
--- a/src/GridGenerator/grid/GridBuilder/GridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
@@ -28,6 +28,7 @@ class PolyDataWriterWrapper;
 template <typename T>
 class BoundingBox;
 
+struct Grid;
 
 class GridBuilder
 {
@@ -48,7 +49,7 @@ public:
     virtual void writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level) = 0;
     virtual void writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const = 0;
 
-	virtual std::shared_ptr<GridWrapper> getGridWrapper(int level, int box) = 0;
+	virtual std::shared_ptr<Grid> getGrid(int level, int box) = 0;
 
     virtual void createBoundaryConditions() = 0;
     virtual std::vector<std::vector<std::vector<real> > > getQsValues() const = 0;
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
index fd940a508..a7cfb07bb 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
@@ -3,8 +3,8 @@
 #include <stdio.h>
 #include <iostream>
 #include <GridGenerator/grid/Grid.cuh>
-#include <GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h>
-#include <GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h>
+#include <GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h>
+#include <GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h>
 #include <GridGenerator/grid/partition/Partition.h>
 
 #include <GridGenerator/geometries/Triangle/Triangle.cuh>
@@ -53,28 +53,28 @@ LevelGridBuilder::~LevelGridBuilder()
 
 void LevelGridBuilder::addGrid(uint minX, uint minY, uint minZ, uint maxX, uint maxY, uint maxZ, std::string distribution)
 {
-    uint level = gridWrapper.size();
+    uint level = grids.size();
 
-    Grid grid(3, 3, 3, 12, 12, 12, 0.5, Distribution());
+    //Grid grid(3, 3, 3, 12, 12, 12, 0.5, Distribution());
 
-    for (unsigned int index = 0; index < grid.size; index++)
-    {
-        grid.setNeighborIndices(index);
-        grid.matrixIndex[index] = index;
-        grid.setFieldEntryToFluid(index);
-    }
+    //for (unsigned int index = 0; index < grid.size; index++)
+    //{
+    //    grid.setNeighborIndices(index);
+    //    grid.matrixIndex[index] = index;
+    //    grid.setFieldEntryToFluid(index);
+    //}
 
 
 
-    switch (this->device)
-    {
-    case GenerationDevice::CPU:
-        this->gridWrapper.push_back(std::shared_ptr<GridWrapperCPU>(new GridWrapperCPU(minX, minY, minZ, maxX, maxY, maxZ, distribution)));
-        break;
-    case GenerationDevice::GPU:
-        this->gridWrapper.push_back(std::shared_ptr<GridWrapperGPU>(new GridWrapperGPU(minX, minY, minZ, maxX, maxY, maxZ, distribution)));
-        break;
-    }
+    //switch (this->device)
+    //{
+    //case GenerationDevice::CPU:
+    //    this->gridWrapper.push_back(std::shared_ptr<GridWrapperCPU>(new GridWrapperCPU(minX, minY, minZ, maxX, maxY, maxZ, distribution)));
+    //    break;
+    //case GenerationDevice::GPU:
+    //    this->gridWrapper.push_back(std::shared_ptr<GridWrapperGPU>(new GridWrapperGPU(minX, minY, minZ, maxX, maxY, maxZ, distribution)));
+    //    break;
+    //}
 }
 
 
@@ -93,14 +93,14 @@ void LevelGridBuilder::meshGeometry(std::string input, int level)
 
 void LevelGridBuilder::deleteSolidNodes()
 {
-    this->gridWrapper[0]->deleteSolidNodes();
-    this->gridWrapper[0]->copyDataFromGPU();
+    //this->gridWrapper[0]->deleteSolidNodes();
+    //this->gridWrapper[0]->copyDataFromGPU();
 }
 
 void LevelGridBuilder::flood(Vertex &startFlood, int level)
 {
     checkLevel(level);
-    this->gridWrapper[level]->floodFill(startFlood);
+    //this->gridWrapper[level]->floodFill(startFlood);
 }
 
 void LevelGridBuilder::createBoundaryConditions()
@@ -111,7 +111,7 @@ void LevelGridBuilder::createBoundaryConditions()
 
 unsigned int LevelGridBuilder::getNumberOfNodes(unsigned int level) const
 {
-    return (unsigned int) this->gridWrapper[level]->grid.reducedSize;
+    return (unsigned int) grids[level]->reducedSize;
 }
 
 std::vector<std::vector<std::vector<real> > > LevelGridBuilder::getQsValues() const
@@ -132,7 +132,7 @@ std::vector<std::string> LevelGridBuilder::getTypeOfBoundaryConditions() const
 void LevelGridBuilder::writeGridToVTK(std::string output, int level)
 {
    checkLevel(level);
-   GridVTKWriter::writeGridToVTK(this->gridWrapper[level]->grid, output);
+   GridVTKWriter::writeGridToVTK(*grids[level].get(), output);
 }
 
 
@@ -147,22 +147,22 @@ void LevelGridBuilder::writeSimulationFiles(std::string output, BoundingBox<int>
     //SimulationFileWriter::writeSimulationFiles(output, coords, qs, writeFilesBinary, this->gridKernels[level]->grid, this->transformators[level]);
 }
 
-std::shared_ptr<GridWrapper> LevelGridBuilder::getGridWrapper(int level, int box)
+std::shared_ptr<Grid> LevelGridBuilder::getGrid(int level, int box)
 {
-    return this->gridWrapper[level];
+    return this->grids[level];
 }
 
 void LevelGridBuilder::checkLevel(int level)
 {
-    if (level >= gridWrapper.size()) { std::cout << "wrong level input... return to caller\n"; return; }
+    if (level >= grids.size()) { std::cout << "wrong level input... return to caller\n"; return; }
 }
 
 
 void LevelGridBuilder::getDimensions(int &nx, int &ny, int &nz, const int level) const
 {
-    nx = this->gridWrapper[level]->grid.nx;
-    ny = this->gridWrapper[level]->grid.ny;
-    nz = this->gridWrapper[level]->grid.nz;
+    nx = grids[level]->nx;
+    ny = grids[level]->ny;
+    nz = grids[level]->nz;
 }
 
 void LevelGridBuilder::getNodeValues(real *xCoords, real *yCoords, real *zCoords, unsigned int *neighborX, unsigned int *neighborY, unsigned int *neighborZ, unsigned int *geo, const int level) const
@@ -175,7 +175,7 @@ void LevelGridBuilder::getNodeValues(real *xCoords, real *yCoords, real *zCoords
     neighborZ[0] = 0;
     geo[0] = GEOSOLID;
 
-    Grid grid = this->gridWrapper[level]->grid;
+    Grid grid = *grids[level].get();
 
     for (int i = 0; i < grid.reducedSize; i++)
     {
@@ -234,7 +234,7 @@ void LevelGridBuilder::setPressValues(real* RhoBC, int* kN, int channelSide, int
 /*---------------------------------------------------------------------------------*/
 void LevelGridBuilder::createBCVectors()
 {
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
     for (int i = 0; i < grid.reducedSize; i++)
     {
         real x, y, z;
@@ -257,7 +257,8 @@ void LevelGridBuilder::addShortQsToVector(int index)
     uint32_t qKey = 0;
     std::vector<real> qNode;
 
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
+
     for (int i = grid.d.dir_end; i >= 0; i--)
     {
         int qIndex = i * grid.size + grid.matrixIndex[index];
@@ -282,7 +283,8 @@ void LevelGridBuilder::addQsToVector(int index)
     std::vector<real> qNode;
     qNode.push_back((real)index);
 
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
+
     for (int i = grid.d.dir_end; i >= 0; i--)
     {
         int qIndex = i * grid.size + grid.matrixIndex[index];
@@ -301,7 +303,8 @@ void LevelGridBuilder::fillRBForNode(int x, int y, int z, int index, int directi
     uint32_t qKey = 0;
     std::vector<real> qNode;
 
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
+
     for (int i = grid.d.dir_end; i >= 0; i--)
     {
         if (grid.d.dirs[i * DIMENSION + direction] != directionSign)
@@ -321,7 +324,8 @@ void LevelGridBuilder::fillRBForNode(int x, int y, int z, int index, int directi
 
 void LevelGridBuilder::writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const
 {
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
+
     //std::shared_ptr<PolyDataWriterWrapper> writer = std::shared_ptr<PolyDataWriterWrapper>(new PolyDataWriterWrapper());
     for (int index = 0; index < Qs[GEOMQS].size(); index++)
     {
@@ -334,7 +338,8 @@ void LevelGridBuilder::writeArrows(std::string fileName, std::shared_ptr<ArrowTr
 
 void LevelGridBuilder::writeArrow(const int i, const int qi, const Vertex& startNode, std::shared_ptr<const ArrowTransformator> trans/*, std::shared_ptr<PolyDataWriterWrapper> writer*/) const
 {
-    Grid grid = this->gridWrapper[0]->grid;
+    Grid grid = *grids[0].get();
+
     real qval = Qs[GEOMQS][i][qi + 1];
     if (qval > 0.0f)
     {
@@ -350,13 +355,13 @@ void LevelGridBuilder::writeArrow(const int i, const int qi, const Vertex& start
 Vertex LevelGridBuilder::getVertex(int matrixIndex) const
 {
     real x, y, z;
-    this->gridWrapper[0]->grid.transIndexToCoords(matrixIndex, x, y, z);
+    this->grids[0]->transIndexToCoords(matrixIndex, x, y, z);
     return Vertex(x,y,z);
 }
 
 int LevelGridBuilder::getMatrixIndex(int i) const
 {
     int index = (int)Qs[GEOMQS][i][0];
-    return this->gridWrapper[0]->grid.matrixIndex[index];
+    return this->grids[0]->matrixIndex[index];
 }
 
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
index e9cbe8def..0b598cb11 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
@@ -11,7 +11,7 @@
 #include "GridBuilder.h"
 
 struct Vertex;
-class GridWrapper;
+struct Grid;
 class Transformator;
 class ArrowTransformator;
 class PolyDataWriterWrapper;
@@ -39,7 +39,7 @@ public:
 	VF_PUBLIC virtual void writeGridToVTK(std::string output, int level);
 	VF_PUBLIC virtual void writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level);
 
-	VF_PUBLIC virtual std::shared_ptr<GridWrapper> getGridWrapper(int level, int box);
+	VF_PUBLIC virtual std::shared_ptr<Grid> getGrid(int level, int box);
 
     VF_PUBLIC virtual void createBoundaryConditions();
 
@@ -62,7 +62,7 @@ public:
 protected:
     GenerationDevice device;
 
-    std::vector<std::shared_ptr<GridWrapper> > gridWrapper;
+    std::vector<std::shared_ptr<Grid> > grids;
 
 
     std::vector<std::vector<std::vector<real> > > Qs;
diff --git a/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.cpp b/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.cpp
index 148834ec1..6b3453402 100644
--- a/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.cpp
+++ b/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.cpp
@@ -1,541 +1,541 @@
-#include "ParallelGridBuilder.h"
-
-#include "mpi.h"
-
-#include <stdio.h>
-#include <iostream>
-#include <GridGenerator/grid/Grid.cuh>
-#include <GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h>
-#include <GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h>
-#include <GridGenerator/grid/partition/Partition.h>
-
-#include <GridGenerator/geometries/Triangle/Triangle.cuh>
-#include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
-#include <GridGenerator/geometries/Geometry/Geometry.cuh>
-
-#include <GridGenerator/utilities/Transformator/Transformator.h>
-
-#include <GridGenerator/io/GridVTKWriter/GridVTKWriter.h>
-#include <GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h>
-#include <GridGenerator/io/VTKWriterWrapper/UnstructuredGridWrapper.h>
-#include <GridGenerator/io/VTKWriterWrapper/PolyDataWriterWrapper.h>
-
-#include <GridGenerator/grid/NodeValues.h>
-
-#include <GridGenerator/geometries/Arrow/ArrowImp.h>
-#include <GridGenerator/utilities/Transformator/ArrowTransformator.h>
-
-#include <utilities/logger/Logger.h>
-
-
-#include <utilities/StringUtil/StringUtil.h>
-
-#include <GridGenerator/geometries/Geometry/Serialization/GeometryMemento.h>
-
-#include <boost/archive/text_iarchive.hpp>
-#include <boost/archive/text_oarchive.hpp>
-
-#include <boost/archive/binary_iarchive.hpp>
-#include <boost/archive/binary_oarchive.hpp>
-
-void serialize(const GeometryMemento &memento, const std::string &filename)
-{
-    std::ofstream ofs(filename, std::ios::binary);
-    boost::archive::binary_oarchive oa(ofs);
-    oa << memento;
-}
-void deserialize(GeometryMemento &memento, const std::string &filename)
-{
-    std::ifstream ifs(filename, std::ios::binary);
-    boost::archive::binary_iarchive ia(ifs);
-    ia >> memento;
-}
-
-#define GEOFLUID 19
-#define GEOSOLID 16
-
-
-ParallelGridBuilder::ParallelGridBuilder(GenerationDevice device) : device(device)
-{
-    this->Qs.resize(QFILES);
-    this->channelBoundaryConditions.resize(6);
-    channelBoundaryConditions[0] = "periodic";
-    channelBoundaryConditions[1] = "periodic";
-    channelBoundaryConditions[2] = "periodic";
-    channelBoundaryConditions[3] = "periodic";
-    channelBoundaryConditions[4] = "periodic";
-    channelBoundaryConditions[5] = "periodic";
-}
-
-
-ParallelGridBuilder::~ParallelGridBuilder()
-{
-
-}
-
-void ParallelGridBuilder::meshGeometry(std::string input, int level)
-{
-    checkLevel(level);
-
-    for (int i = 0; i < rankTasks.size(); i += 2)
-    {
-        int levelTask = rankTasks[i];
-
-        int index = rankTasks[i + 1];
-
-        if (levelTask == level)
-        {
-            Geometry* geometry;
-            if (StringUtil::endsWith(input, ".stl") || StringUtil::endsWith(input, ".STL"))
-            {
-                geometry = new Geometry(input, boxes[level][index], transformators[level].get());
-                printf("Serialize State\n");
-                GeometryMemento memento = geometry->getState();
-                serialize(memento, input + "state");
-            }
-            else {
-                *logging::out << logging::Logger::INTERMEDIATE << "start reading memento ...\n";
-
-                clock_t begin = clock();
-                geometry = new Geometry();
-                GeometryMemento memento;
-                deserialize(memento, input);
-                geometry->setState(memento);
-                clock_t end = clock();
-
-                real time = real(end - begin) / CLOCKS_PER_SEC;
-                *logging::out << logging::Logger::INTERMEDIATE << "time reading memento: " << SSTR(time) << "s\n";
-            }
-            
-            if (geometry->size > 0)
-                this->gridKernels[level][index]->meshGrid(*geometry);
-            //this->gridKernels[level][index]->copyDataFromGPU();
-            delete geometry;
-        }
-    }
-}
-
-void ParallelGridBuilder::deleteSolidNodes()
-{
-    this->gridKernels[0][0]->deleteSolidNodes();
-    this->gridKernels[0][0]->copyDataFromGPU();
-}
-
-void ParallelGridBuilder::flood(Vertex &startFlood, int level)
-{
-    checkLevel(level);
-    this->gridKernels[level][0]->floodFill(startFlood);
-}
-
-void ParallelGridBuilder::createBoundaryConditions()
-{
-    this->createBCVectors();
-}
-
-
-unsigned int ParallelGridBuilder::getNumberOfNodes(unsigned int level) const
-{
-    return (unsigned int) this->gridKernels[level][0]->grid.reducedSize;
-}
-
-std::vector<std::vector<std::vector<real> > > ParallelGridBuilder::getQsValues() const
-{
-    return this->Qs;
-}
-
-int ParallelGridBuilder::getBoundaryConditionSize(int rb) const
-{
-    return (int)Qs[rb].size();
-}
-
-std::vector<std::string> ParallelGridBuilder::getTypeOfBoundaryConditions() const
-{
-    return this->channelBoundaryConditions;
-}
-
-void ParallelGridBuilder::writeGridToVTK(std::string output, int level)
-{
-    checkLevel(level);
-    int rank;
-    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-    for (int i = 0; i < rankTasks.size(); i += 2) 
-    {
-        int levelTask = rankTasks[i];
-        int index = rankTasks[i + 1];
-
-        if (levelTask == level) {
-            std::stringstream ss;
-            ss << output << rank;
-            GridVTKWriter::writeGridToVTK(this->gridKernels[level][index]->grid, ss.str(), this->transformators[level], true);
-        }
-    }
-}
-
-
-void ParallelGridBuilder::writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level)
-{
-    //checkLevel(level);
-    //UnstructuredParallelGridBuilder builder;
-    //builder.buildUnstructuredGrid(this->gridKernels[level]->grid, nodesDelete);
-
-    //std::vector<Node> coords = builder.getCoordsVec();
-    //std::vector<std::vector<std::vector<real> > > qs = builder.getQsValues();
-    //SimulationFileWriter::writeSimulationFiles(output, coords, qs, writeFilesBinary, this->gridKernels[level]->grid, this->transformators[level]);
-}
-
-std::shared_ptr<GridWrapper> ParallelGridBuilder::getGridWrapper(int level, int box)
-{
-    return this->gridKernels[level][box];
-}
-
-void ParallelGridBuilder::checkLevel(int level)
-{
-    if (level >= boxes.size()) { std::cout << "wrong level input... return to caller\n"; return; }
-}
-
-
-void ParallelGridBuilder::addGrid(real length, real width, real high, real delta, std::string distribution, std::shared_ptr<Transformator> trans)
-{
-    this->transformators.push_back(trans);
-
-    int rank;
-    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-    this->setCudaDevice(rank);
-    this->setNumberOfNodes(length, width, high, delta);
-    this->rebuildBoxes();
-
-    if (rank == 0)
-        this->sendTasks();
-    else
-        this->receiveTasks();
-
-    this->createGridKernels(distribution);
-}
-
-void ParallelGridBuilder::createGridKernels(std::string distribution)
-{
-    for (int i = 0; i < rankTasks.size(); i += 2)
-    {
-        int level = rankTasks[i];
-        int index = rankTasks[i + 1];
-
-        switch (this->device)
-        {
-        case GenerationDevice::CPU:
-            this->gridKernels[level][index] = std::shared_ptr<GridWrapperCPU>(new GridWrapperCPU(this->boxes[level][index], distribution));
-            break;
-        case GenerationDevice::GPU:
-            this->gridKernels[level][index] = std::shared_ptr<GridWrapperGPU>(new GridWrapperGPU(this->boxes[level][index], distribution));
-            break;
-        }
-    }
-}
-
-
-void ParallelGridBuilder::setNumberOfNodes(real length, real width, real high, real delta)
-{
-    int nx = (int)(length / delta);
-    int ny = (int)(width / delta);
-    int nz = (int)(high / delta);
-
-    std::vector<int> dim = { nx,ny,nz };
-    this->gridDimensions.push_back(dim);
-
-    this->printMasterInformation(nx, ny, nz);
-}
-
-void ParallelGridBuilder::printMasterInformation(int nx, int ny, int nz)
-{
-    *logging::out << "global field dimension : " << SSTR(nx) << ", " << SSTR(ny) << ", " << SSTR(nz) << "\n";
-    *logging::out << "global field size : " << SSTR(nx * ny * nz) << "\n";
-    *logging::out << "------------------------------------------- \n";
-}
-
-void ParallelGridBuilder::setCudaDevice(int rank)
-{
-    int countDevices;
-    cudaGetDeviceCount(&countDevices);
-#ifdef __unix__
-    char hostname[1024];
-    hostname[1023] = '\0';
-    gethostname(hostname, 1023);
-
-    std::string hostnameStr(hostname);
-    int device = rank % 4;
-    cudaSetDevice(device);
-    logging::Logger::getInstance()->logTerminal("Hostname: " + hostnameStr + ", device: " + SSTR(device) + "/" + SSTR(countDevices) + "\n");
-#else
-    cudaSetDevice(1);
-#endif
-}
-
-void ParallelGridBuilder::rebuildBoxes()
-{
-    int numProcess;
-    MPI_Comm_size(MPI_COMM_WORLD, &numProcess);
-    int actualLevelSize = (int)this->boxes.size() + 1;
-    this->boxes.resize(actualLevelSize);
-    this->gridKernels.resize(actualLevelSize);
-
-    //for each level rebuild boxes 
-    for (int i = 0; i < actualLevelSize; i++) {
-        this->boxes[i] = Partition::getProcessBoxes(numProcess / actualLevelSize, gridDimensions[i][0], gridDimensions[i][1], gridDimensions[i][2]);
-        this->gridKernels[i].resize(this->boxes[i].size());
-    }
-}
-
-void ParallelGridBuilder::sendTasks()
-{
-    int numProcess;
-    MPI_Comm_size(MPI_COMM_WORLD, &numProcess);
-    std::vector<std::vector<int> >tasks = Partition::partitionBoxes(this->boxes, numProcess, transformators);
-
-    rankTasks.resize(tasks[0].size());
-    for (int i = 0; i < rankTasks.size(); i++) {
-        rankTasks[i] = tasks[0][i];
-    }
-
-    for (int i = 1; i < numProcess; i++) {
-        int numOfBoxes = (int)tasks[i].size();
-        MPI_Send(&numOfBoxes, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
-        MPI_Send(&tasks[i][0], numOfBoxes, MPI_INT, i, 1, MPI_COMM_WORLD);
-    }
-}
-
-void ParallelGridBuilder::receiveTasks()
-{
-    int numOfBoxes;
-    MPI_Status status;
-    MPI_Recv(&numOfBoxes, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
-    rankTasks.resize(numOfBoxes);
-
-    int *boxNumbers = new int[numOfBoxes];
-    MPI_Recv(boxNumbers, numOfBoxes, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
-
-    for (int i = 0; i < numOfBoxes; i++) {
-        rankTasks[i] = boxNumbers[i];
-    }
-    delete[] boxNumbers;
-}
-
-void ParallelGridBuilder::writeBoxes(std::string name)
-{
-    //int rank;
-    //MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-    //UnstructuredGridWrapper writer;
-    //for (int i = 0; i < rankTasks.size(); i += 2) {
-    //    int level = rankTasks[i];
-    //    int index = rankTasks[i + 1];
-    //    BoundingBox<real> box = boxes[level][index];
-    //    transformators[level]->transformGridToWorld(box);
-    //    writer.addBoundingBox(box, rank);
-    //}
-    //writer.writeUnstructuredGridToFile(name);
-}
-
-
-void ParallelGridBuilder::getDimensions(int &nx, int &ny, int &nz, const int level) const
-{
-    nx = this->gridKernels[level][0]->grid.nx;
-    ny = this->gridKernels[level][0]->grid.ny;
-    nz = this->gridKernels[level][0]->grid.nz;
-}
-
-void ParallelGridBuilder::getNodeValues(real *xCoords, real *yCoords, real *zCoords, unsigned int *neighborX, unsigned int *neighborY, unsigned int *neighborZ, unsigned int *geo, const int level) const
-{
-    xCoords[0] = 0;
-    yCoords[0] = 0;
-    zCoords[0] = 0;
-    neighborX[0] = 0;
-    neighborY[0] = 0;
-    neighborZ[0] = 0;
-    geo[0] = GEOSOLID;
-
-    Grid grid = this->gridKernels[level][0]->grid;
-
-    for (int i = 0; i < grid.reducedSize; i++)
-    {
-        real x, y, z;
-        grid.transIndexToCoords(grid.matrixIndex[i], x, y, z);
-
-        xCoords[i + 1] = x;
-        yCoords[i + 1] = y;
-        zCoords[i + 1] = z;
-        neighborX[i + 1] = (unsigned int)(grid.neighborIndexX[grid.matrixIndex[i]] + 1);
-        neighborY[i + 1] = (unsigned int)(grid.neighborIndexY[grid.matrixIndex[i]] + 1);
-        neighborZ[i + 1] = (unsigned int)(grid.neighborIndexZ[grid.matrixIndex[i]] + 1);
-        geo[i + 1] = (unsigned int)grid.isSolid(grid.matrixIndex[i]) ? GEOSOLID : GEOFLUID;
-    }
-}
-
-void ParallelGridBuilder::setQs(real** q27, int* k, int channelSide, unsigned int level) const
-{
-    for (int index = 0; index < Qs[channelSide].size(); index++) {
-        k[index] = (int)Qs[channelSide][index][0];
-        for (int column = 1; column < Qs[channelSide][index].size(); column++) {
-            q27[column - 1][index] = Qs[channelSide][index][column];
-
-        }
-    }
-}
-
-void ParallelGridBuilder::setOutflowValues(real* RhoBC, int* kN, int channelSide, int level) const
-{
-    for (int index = 0; index < Qs[channelSide].size(); index++) {
-        RhoBC[index] = 0.0;
-        kN[index] = 0;
-    }
-}
-
-void ParallelGridBuilder::setVelocityValues(real* vx, real* vy, real* vz, int channelSide, int level) const
-{
-    for (int index = 0; index < Qs[channelSide].size(); index++) {
-        vx[index] = 0.0;
-        vy[index] = 0.0;
-        vz[index] = 0.0;
-    }
-}
-
-void ParallelGridBuilder::setPressValues(real* RhoBC, int* kN, int channelSide, int level) const
-{
-    for (int index = 0; index < Qs[channelSide].size(); index++) {
-        RhoBC[index] = 0.0;
-        kN[index] = 0;
-    }
-}
-
-
-/*#################################################################################*/
-/*---------------------------------private methods---------------------------------*/
-/*---------------------------------------------------------------------------------*/
-void ParallelGridBuilder::createBCVectors()
-{
-    Grid grid = this->gridKernels[0][0]->grid;
-    for (int i = 0; i < grid.reducedSize; i++)
-    {
-        real x, y, z;
-        grid.transIndexToCoords(grid.matrixIndex[i], x, y, z);
-
-        if (grid.field[grid.matrixIndex[i]] == Q) /*addShortQsToVector(i);*/ addQsToVector(i);
-        if (x == 0 && y < grid.ny - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 0, -1, INLETQS);
-        if (x == grid.nx - 2 && y < grid.ny - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 0, 1, OUTLETQS);
-
-        if (z == grid.nz - 2 && x < grid.nx - 1 && y < grid.ny - 1) fillRBForNode(x, y, z, i, 2, 1, TOPQS);
-        if (z == 0 && x < grid.nx - 1 && y < grid.ny - 1) fillRBForNode(x, y, z, i, 2, -1, BOTTOMQS);
-
-        if (y == 0 && x < grid.nx - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 1, -1, FRONTQS);
-        if (y == grid.ny - 2 && x < grid.nx - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 1, 1, BACKQS);
-    }
-}
-
-void ParallelGridBuilder::addShortQsToVector(int index)
-{
-    uint32_t qKey = 0;
-    std::vector<real> qNode;
-
-    Grid grid = this->gridKernels[0][0]->grid;
-    for (int i = grid.d.dir_end; i >= 0; i--)
-    {
-        int qIndex = i * grid.size + grid.matrixIndex[index];
-        real q = grid.d.f[qIndex];
-        if (q > 0) {
-            //printf("Q%d (old:%d, new:%d), : %2.8f \n", i, coordsVec[index].matrixIndex, index, grid.d.f[i * grid.size + coordsVec[index].matrixIndex]);
-            qKey += (uint32_t)pow(2, 26 - i);
-            qNode.push_back(q);
-        }
-    }
-    if (qKey > 0) {
-        real transportKey = *((real*)&qKey);
-        qNode.push_back(transportKey);
-        qNode.push_back((real)index);
-        Qs[GEOMQS].push_back(qNode);
-    }
-    qNode.clear();
-}
-
-void ParallelGridBuilder::addQsToVector(int index)
-{
-    std::vector<real> qNode;
-    qNode.push_back((real)index);
-
-    Grid grid = this->gridKernels[0][0]->grid;
-    for (int i = grid.d.dir_end; i >= 0; i--)
-    {
-        int qIndex = i * grid.size + grid.matrixIndex[index];
-        real q = grid.d.f[qIndex];
-        if (q > 0)
-            qNode.push_back(q);
-        else
-            qNode.push_back(-1);
-    }
-    Qs[GEOMQS].push_back(qNode);
-    qNode.clear();
-}
-
-void ParallelGridBuilder::fillRBForNode(int x, int y, int z, int index, int direction, int directionSign, int rb)
-{
-    uint32_t qKey = 0;
-    std::vector<real> qNode;
-
-    Grid grid = this->gridKernels[0][0]->grid;
-    for (int i = grid.d.dir_end; i >= 0; i--)
-    {
-        if (grid.d.dirs[i * DIMENSION + direction] != directionSign)
-            continue;
-
-        qKey += (uint32_t)pow(2, 26 - i);
-        qNode.push_back(0.5f);
-    }
-    if (qKey > 0) {
-        real transportKey = *((real*)&qKey);
-        qNode.push_back(transportKey);
-        qNode.push_back((real)index);
-        Qs[rb].push_back(qNode);
-    }
-    qNode.clear();
-}
-
-void ParallelGridBuilder::writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const
-{
-    Grid grid = this->gridKernels[0][0]->grid;
-    //std::shared_ptr<PolyDataWriterWrapper> writer = std::shared_ptr<PolyDataWriterWrapper>(new PolyDataWriterWrapper());
-    for (int index = 0; index < Qs[GEOMQS].size(); index++)
-    {
-        Vertex startNode = getVertex(getMatrixIndex(index));
-        //for (int qi = grid.d.dir_start; qi <= grid.d.dir_end; qi++)
-            //writeArrow(index, qi, startNode, trans, writer);
-    }
-    //writer->writePolyDataToFile(fileName);
-}
-
-void ParallelGridBuilder::writeArrow(const int i, const int qi, const Vertex& startNode, std::shared_ptr<const ArrowTransformator> trans/*, std::shared_ptr<PolyDataWriterWrapper> writer*/) const
-{
-    Grid grid = this->gridKernels[0][0]->grid;
-    real qval = Qs[GEOMQS][i][qi + 1];
-    if (qval > 0.0f)
-    {
-        int qReverse = grid.d.dir_end - qi;
-        Vertex dir((real)grid.d.dirs[qReverse * DIMENSION + 0], (real)grid.d.dirs[qReverse* DIMENSION + 1], (real)grid.d.dirs[qReverse * DIMENSION + 2]);
-        Vertex nodeOnGeometry(startNode + (dir * qval));
-        std::shared_ptr<Arrow> arrow = ArrowImp::make(startNode, nodeOnGeometry);
-        trans->transformGridToWorld(arrow);
-        //writer->addVectorArrow(arrow);
-    }
-}
-
-Vertex ParallelGridBuilder::getVertex(int matrixIndex) const
-{
-    real x, y, z;
-    this->gridKernels[0][0]->grid.transIndexToCoords(matrixIndex, x, y, z);
-    return Vertex((real)x, (real)y, (real)z);
-}
-
-int ParallelGridBuilder::getMatrixIndex(int i) const
-{
-    int index = (int)Qs[GEOMQS][i][0];
-    return this->gridKernels[0][0]->grid.matrixIndex[index];
-}
-
+//#include "ParallelGridBuilder.h"
+//
+//#include "mpi.h"
+//
+//#include <stdio.h>
+//#include <iostream>
+//#include <GridGenerator/grid/Grid.cuh>
+//#include <GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h>
+//#include <GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h>
+//#include <GridGenerator/grid/partition/Partition.h>
+//
+//#include <GridGenerator/geometries/Triangle/Triangle.cuh>
+//#include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
+//#include <GridGenerator/geometries/Geometry/Geometry.cuh>
+//
+//#include <GridGenerator/utilities/Transformator/Transformator.h>
+//
+//#include <GridGenerator/io/GridVTKWriter/GridVTKWriter.h>
+//#include <GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h>
+//#include <GridGenerator/io/VTKWriterWrapper/UnstructuredGridWrapper.h>
+//#include <GridGenerator/io/VTKWriterWrapper/PolyDataWriterWrapper.h>
+//
+//#include <GridGenerator/grid/NodeValues.h>
+//
+//#include <GridGenerator/geometries/Arrow/ArrowImp.h>
+//#include <GridGenerator/utilities/Transformator/ArrowTransformator.h>
+//
+//#include <utilities/logger/Logger.h>
+//
+//
+//#include <utilities/StringUtil/StringUtil.h>
+//
+//#include <GridGenerator/geometries/Geometry/Serialization/GeometryMemento.h>
+//
+//#include <boost/archive/text_iarchive.hpp>
+//#include <boost/archive/text_oarchive.hpp>
+//
+//#include <boost/archive/binary_iarchive.hpp>
+//#include <boost/archive/binary_oarchive.hpp>
+//
+//void serialize(const GeometryMemento &memento, const std::string &filename)
+//{
+//    std::ofstream ofs(filename, std::ios::binary);
+//    boost::archive::binary_oarchive oa(ofs);
+//    oa << memento;
+//}
+//void deserialize(GeometryMemento &memento, const std::string &filename)
+//{
+//    std::ifstream ifs(filename, std::ios::binary);
+//    boost::archive::binary_iarchive ia(ifs);
+//    ia >> memento;
+//}
+//
+//#define GEOFLUID 19
+//#define GEOSOLID 16
+//
+//
+//ParallelGridBuilder::ParallelGridBuilder(GenerationDevice device) : device(device)
+//{
+//    this->Qs.resize(QFILES);
+//    this->channelBoundaryConditions.resize(6);
+//    channelBoundaryConditions[0] = "periodic";
+//    channelBoundaryConditions[1] = "periodic";
+//    channelBoundaryConditions[2] = "periodic";
+//    channelBoundaryConditions[3] = "periodic";
+//    channelBoundaryConditions[4] = "periodic";
+//    channelBoundaryConditions[5] = "periodic";
+//}
+//
+//
+//ParallelGridBuilder::~ParallelGridBuilder()
+//{
+//
+//}
+//
+//void ParallelGridBuilder::meshGeometry(std::string input, int level)
+//{
+//    checkLevel(level);
+//
+//    for (int i = 0; i < rankTasks.size(); i += 2)
+//    {
+//        int levelTask = rankTasks[i];
+//
+//        int index = rankTasks[i + 1];
+//
+//        if (levelTask == level)
+//        {
+//            Geometry* geometry;
+//            if (StringUtil::endsWith(input, ".stl") || StringUtil::endsWith(input, ".STL"))
+//            {
+//                geometry = new Geometry(input, boxes[level][index], transformators[level].get());
+//                printf("Serialize State\n");
+//                GeometryMemento memento = geometry->getState();
+//                serialize(memento, input + "state");
+//            }
+//            else {
+//                *logging::out << logging::Logger::INTERMEDIATE << "start reading memento ...\n";
+//
+//                clock_t begin = clock();
+//                geometry = new Geometry();
+//                GeometryMemento memento;
+//                deserialize(memento, input);
+//                geometry->setState(memento);
+//                clock_t end = clock();
+//
+//                real time = real(end - begin) / CLOCKS_PER_SEC;
+//                *logging::out << logging::Logger::INTERMEDIATE << "time reading memento: " << SSTR(time) << "s\n";
+//            }
+//            
+//            if (geometry->size > 0)
+//                this->gridKernels[level][index]->meshGrid(*geometry);
+//            //this->gridKernels[level][index]->copyDataFromGPU();
+//            delete geometry;
+//        }
+//    }
+//}
+//
+//void ParallelGridBuilder::deleteSolidNodes()
+//{
+//    this->gridKernels[0][0]->deleteSolidNodes();
+//    this->gridKernels[0][0]->copyDataFromGPU();
+//}
+//
+//void ParallelGridBuilder::flood(Vertex &startFlood, int level)
+//{
+//    checkLevel(level);
+//    this->gridKernels[level][0]->floodFill(startFlood);
+//}
+//
+//void ParallelGridBuilder::createBoundaryConditions()
+//{
+//    this->createBCVectors();
+//}
+//
+//
+//unsigned int ParallelGridBuilder::getNumberOfNodes(unsigned int level) const
+//{
+//    return (unsigned int) this->gridKernels[level][0]->grid.reducedSize;
+//}
+//
+//std::vector<std::vector<std::vector<real> > > ParallelGridBuilder::getQsValues() const
+//{
+//    return this->Qs;
+//}
+//
+//int ParallelGridBuilder::getBoundaryConditionSize(int rb) const
+//{
+//    return (int)Qs[rb].size();
+//}
+//
+//std::vector<std::string> ParallelGridBuilder::getTypeOfBoundaryConditions() const
+//{
+//    return this->channelBoundaryConditions;
+//}
+//
+//void ParallelGridBuilder::writeGridToVTK(std::string output, int level)
+//{
+//    checkLevel(level);
+//    int rank;
+//    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+//
+//    for (int i = 0; i < rankTasks.size(); i += 2) 
+//    {
+//        int levelTask = rankTasks[i];
+//        int index = rankTasks[i + 1];
+//
+//        if (levelTask == level) {
+//            std::stringstream ss;
+//            ss << output << rank;
+//            GridVTKWriter::writeGridToVTK(this->gridKernels[level][index]->grid, ss.str(), this->transformators[level], true);
+//        }
+//    }
+//}
+//
+//
+//void ParallelGridBuilder::writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level)
+//{
+//    //checkLevel(level);
+//    //UnstructuredParallelGridBuilder builder;
+//    //builder.buildUnstructuredGrid(this->gridKernels[level]->grid, nodesDelete);
+//
+//    //std::vector<Node> coords = builder.getCoordsVec();
+//    //std::vector<std::vector<std::vector<real> > > qs = builder.getQsValues();
+//    //SimulationFileWriter::writeSimulationFiles(output, coords, qs, writeFilesBinary, this->gridKernels[level]->grid, this->transformators[level]);
+//}
+//
+//std::shared_ptr<GridWrapper> ParallelGridBuilder::getGridWrapper(int level, int box)
+//{
+//    return this->gridKernels[level][box];
+//}
+//
+//void ParallelGridBuilder::checkLevel(int level)
+//{
+//    if (level >= boxes.size()) { std::cout << "wrong level input... return to caller\n"; return; }
+//}
+//
+//
+//void ParallelGridBuilder::addGrid(real length, real width, real high, real delta, std::string distribution, std::shared_ptr<Transformator> trans)
+//{
+//    this->transformators.push_back(trans);
+//
+//    int rank;
+//    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+//
+//    this->setCudaDevice(rank);
+//    this->setNumberOfNodes(length, width, high, delta);
+//    this->rebuildBoxes();
+//
+//    if (rank == 0)
+//        this->sendTasks();
+//    else
+//        this->receiveTasks();
+//
+//    this->createGridKernels(distribution);
+//}
+//
+//void ParallelGridBuilder::createGridKernels(std::string distribution)
+//{
+//    for (int i = 0; i < rankTasks.size(); i += 2)
+//    {
+//        int level = rankTasks[i];
+//        int index = rankTasks[i + 1];
+//
+//        switch (this->device)
+//        {
+//        case GenerationDevice::CPU:
+//            this->gridKernels[level][index] = std::shared_ptr<GridWrapperCPU>(new GridWrapperCPU(this->boxes[level][index], distribution));
+//            break;
+//        case GenerationDevice::GPU:
+//            this->gridKernels[level][index] = std::shared_ptr<GridWrapperGPU>(new GridWrapperGPU(this->boxes[level][index], distribution));
+//            break;
+//        }
+//    }
+//}
+//
+//
+//void ParallelGridBuilder::setNumberOfNodes(real length, real width, real high, real delta)
+//{
+//    int nx = (int)(length / delta);
+//    int ny = (int)(width / delta);
+//    int nz = (int)(high / delta);
+//
+//    std::vector<int> dim = { nx,ny,nz };
+//    this->gridDimensions.push_back(dim);
+//
+//    this->printMasterInformation(nx, ny, nz);
+//}
+//
+//void ParallelGridBuilder::printMasterInformation(int nx, int ny, int nz)
+//{
+//    *logging::out << "global field dimension : " << SSTR(nx) << ", " << SSTR(ny) << ", " << SSTR(nz) << "\n";
+//    *logging::out << "global field size : " << SSTR(nx * ny * nz) << "\n";
+//    *logging::out << "------------------------------------------- \n";
+//}
+//
+//void ParallelGridBuilder::setCudaDevice(int rank)
+//{
+//    int countDevices;
+//    cudaGetDeviceCount(&countDevices);
+//#ifdef __unix__
+//    char hostname[1024];
+//    hostname[1023] = '\0';
+//    gethostname(hostname, 1023);
+//
+//    std::string hostnameStr(hostname);
+//    int device = rank % 4;
+//    cudaSetDevice(device);
+//    logging::Logger::getInstance()->logTerminal("Hostname: " + hostnameStr + ", device: " + SSTR(device) + "/" + SSTR(countDevices) + "\n");
+//#else
+//    cudaSetDevice(1);
+//#endif
+//}
+//
+//void ParallelGridBuilder::rebuildBoxes()
+//{
+//    int numProcess;
+//    MPI_Comm_size(MPI_COMM_WORLD, &numProcess);
+//    int actualLevelSize = (int)this->boxes.size() + 1;
+//    this->boxes.resize(actualLevelSize);
+//    this->gridKernels.resize(actualLevelSize);
+//
+//    //for each level rebuild boxes 
+//    for (int i = 0; i < actualLevelSize; i++) {
+//        this->boxes[i] = Partition::getProcessBoxes(numProcess / actualLevelSize, gridDimensions[i][0], gridDimensions[i][1], gridDimensions[i][2]);
+//        this->gridKernels[i].resize(this->boxes[i].size());
+//    }
+//}
+//
+//void ParallelGridBuilder::sendTasks()
+//{
+//    int numProcess;
+//    MPI_Comm_size(MPI_COMM_WORLD, &numProcess);
+//    std::vector<std::vector<int> >tasks = Partition::partitionBoxes(this->boxes, numProcess, transformators);
+//
+//    rankTasks.resize(tasks[0].size());
+//    for (int i = 0; i < rankTasks.size(); i++) {
+//        rankTasks[i] = tasks[0][i];
+//    }
+//
+//    for (int i = 1; i < numProcess; i++) {
+//        int numOfBoxes = (int)tasks[i].size();
+//        MPI_Send(&numOfBoxes, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
+//        MPI_Send(&tasks[i][0], numOfBoxes, MPI_INT, i, 1, MPI_COMM_WORLD);
+//    }
+//}
+//
+//void ParallelGridBuilder::receiveTasks()
+//{
+//    int numOfBoxes;
+//    MPI_Status status;
+//    MPI_Recv(&numOfBoxes, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
+//    rankTasks.resize(numOfBoxes);
+//
+//    int *boxNumbers = new int[numOfBoxes];
+//    MPI_Recv(boxNumbers, numOfBoxes, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
+//
+//    for (int i = 0; i < numOfBoxes; i++) {
+//        rankTasks[i] = boxNumbers[i];
+//    }
+//    delete[] boxNumbers;
+//}
+//
+//void ParallelGridBuilder::writeBoxes(std::string name)
+//{
+//    //int rank;
+//    //MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+//
+//    //UnstructuredGridWrapper writer;
+//    //for (int i = 0; i < rankTasks.size(); i += 2) {
+//    //    int level = rankTasks[i];
+//    //    int index = rankTasks[i + 1];
+//    //    BoundingBox<real> box = boxes[level][index];
+//    //    transformators[level]->transformGridToWorld(box);
+//    //    writer.addBoundingBox(box, rank);
+//    //}
+//    //writer.writeUnstructuredGridToFile(name);
+//}
+//
+//
+//void ParallelGridBuilder::getDimensions(int &nx, int &ny, int &nz, const int level) const
+//{
+//    nx = this->gridKernels[level][0]->grid.nx;
+//    ny = this->gridKernels[level][0]->grid.ny;
+//    nz = this->gridKernels[level][0]->grid.nz;
+//}
+//
+//void ParallelGridBuilder::getNodeValues(real *xCoords, real *yCoords, real *zCoords, unsigned int *neighborX, unsigned int *neighborY, unsigned int *neighborZ, unsigned int *geo, const int level) const
+//{
+//    xCoords[0] = 0;
+//    yCoords[0] = 0;
+//    zCoords[0] = 0;
+//    neighborX[0] = 0;
+//    neighborY[0] = 0;
+//    neighborZ[0] = 0;
+//    geo[0] = GEOSOLID;
+//
+//    Grid grid = this->gridKernels[level][0]->grid;
+//
+//    for (int i = 0; i < grid.reducedSize; i++)
+//    {
+//        real x, y, z;
+//        grid.transIndexToCoords(grid.matrixIndex[i], x, y, z);
+//
+//        xCoords[i + 1] = x;
+//        yCoords[i + 1] = y;
+//        zCoords[i + 1] = z;
+//        neighborX[i + 1] = (unsigned int)(grid.neighborIndexX[grid.matrixIndex[i]] + 1);
+//        neighborY[i + 1] = (unsigned int)(grid.neighborIndexY[grid.matrixIndex[i]] + 1);
+//        neighborZ[i + 1] = (unsigned int)(grid.neighborIndexZ[grid.matrixIndex[i]] + 1);
+//        geo[i + 1] = (unsigned int)grid.isSolid(grid.matrixIndex[i]) ? GEOSOLID : GEOFLUID;
+//    }
+//}
+//
+//void ParallelGridBuilder::setQs(real** q27, int* k, int channelSide, unsigned int level) const
+//{
+//    for (int index = 0; index < Qs[channelSide].size(); index++) {
+//        k[index] = (int)Qs[channelSide][index][0];
+//        for (int column = 1; column < Qs[channelSide][index].size(); column++) {
+//            q27[column - 1][index] = Qs[channelSide][index][column];
+//
+//        }
+//    }
+//}
+//
+//void ParallelGridBuilder::setOutflowValues(real* RhoBC, int* kN, int channelSide, int level) const
+//{
+//    for (int index = 0; index < Qs[channelSide].size(); index++) {
+//        RhoBC[index] = 0.0;
+//        kN[index] = 0;
+//    }
+//}
+//
+//void ParallelGridBuilder::setVelocityValues(real* vx, real* vy, real* vz, int channelSide, int level) const
+//{
+//    for (int index = 0; index < Qs[channelSide].size(); index++) {
+//        vx[index] = 0.0;
+//        vy[index] = 0.0;
+//        vz[index] = 0.0;
+//    }
+//}
+//
+//void ParallelGridBuilder::setPressValues(real* RhoBC, int* kN, int channelSide, int level) const
+//{
+//    for (int index = 0; index < Qs[channelSide].size(); index++) {
+//        RhoBC[index] = 0.0;
+//        kN[index] = 0;
+//    }
+//}
+//
+//
+///*#################################################################################*/
+///*---------------------------------private methods---------------------------------*/
+///*---------------------------------------------------------------------------------*/
+//void ParallelGridBuilder::createBCVectors()
+//{
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    for (int i = 0; i < grid.reducedSize; i++)
+//    {
+//        real x, y, z;
+//        grid.transIndexToCoords(grid.matrixIndex[i], x, y, z);
+//
+//        if (grid.field[grid.matrixIndex[i]] == Q) /*addShortQsToVector(i);*/ addQsToVector(i);
+//        if (x == 0 && y < grid.ny - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 0, -1, INLETQS);
+//        if (x == grid.nx - 2 && y < grid.ny - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 0, 1, OUTLETQS);
+//
+//        if (z == grid.nz - 2 && x < grid.nx - 1 && y < grid.ny - 1) fillRBForNode(x, y, z, i, 2, 1, TOPQS);
+//        if (z == 0 && x < grid.nx - 1 && y < grid.ny - 1) fillRBForNode(x, y, z, i, 2, -1, BOTTOMQS);
+//
+//        if (y == 0 && x < grid.nx - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 1, -1, FRONTQS);
+//        if (y == grid.ny - 2 && x < grid.nx - 1 && z < grid.nz - 1) fillRBForNode(x, y, z, i, 1, 1, BACKQS);
+//    }
+//}
+//
+//void ParallelGridBuilder::addShortQsToVector(int index)
+//{
+//    uint32_t qKey = 0;
+//    std::vector<real> qNode;
+//
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    for (int i = grid.d.dir_end; i >= 0; i--)
+//    {
+//        int qIndex = i * grid.size + grid.matrixIndex[index];
+//        real q = grid.d.f[qIndex];
+//        if (q > 0) {
+//            //printf("Q%d (old:%d, new:%d), : %2.8f \n", i, coordsVec[index].matrixIndex, index, grid.d.f[i * grid.size + coordsVec[index].matrixIndex]);
+//            qKey += (uint32_t)pow(2, 26 - i);
+//            qNode.push_back(q);
+//        }
+//    }
+//    if (qKey > 0) {
+//        real transportKey = *((real*)&qKey);
+//        qNode.push_back(transportKey);
+//        qNode.push_back((real)index);
+//        Qs[GEOMQS].push_back(qNode);
+//    }
+//    qNode.clear();
+//}
+//
+//void ParallelGridBuilder::addQsToVector(int index)
+//{
+//    std::vector<real> qNode;
+//    qNode.push_back((real)index);
+//
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    for (int i = grid.d.dir_end; i >= 0; i--)
+//    {
+//        int qIndex = i * grid.size + grid.matrixIndex[index];
+//        real q = grid.d.f[qIndex];
+//        if (q > 0)
+//            qNode.push_back(q);
+//        else
+//            qNode.push_back(-1);
+//    }
+//    Qs[GEOMQS].push_back(qNode);
+//    qNode.clear();
+//}
+//
+//void ParallelGridBuilder::fillRBForNode(int x, int y, int z, int index, int direction, int directionSign, int rb)
+//{
+//    uint32_t qKey = 0;
+//    std::vector<real> qNode;
+//
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    for (int i = grid.d.dir_end; i >= 0; i--)
+//    {
+//        if (grid.d.dirs[i * DIMENSION + direction] != directionSign)
+//            continue;
+//
+//        qKey += (uint32_t)pow(2, 26 - i);
+//        qNode.push_back(0.5f);
+//    }
+//    if (qKey > 0) {
+//        real transportKey = *((real*)&qKey);
+//        qNode.push_back(transportKey);
+//        qNode.push_back((real)index);
+//        Qs[rb].push_back(qNode);
+//    }
+//    qNode.clear();
+//}
+//
+//void ParallelGridBuilder::writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const
+//{
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    //std::shared_ptr<PolyDataWriterWrapper> writer = std::shared_ptr<PolyDataWriterWrapper>(new PolyDataWriterWrapper());
+//    for (int index = 0; index < Qs[GEOMQS].size(); index++)
+//    {
+//        Vertex startNode = getVertex(getMatrixIndex(index));
+//        //for (int qi = grid.d.dir_start; qi <= grid.d.dir_end; qi++)
+//            //writeArrow(index, qi, startNode, trans, writer);
+//    }
+//    //writer->writePolyDataToFile(fileName);
+//}
+//
+//void ParallelGridBuilder::writeArrow(const int i, const int qi, const Vertex& startNode, std::shared_ptr<const ArrowTransformator> trans/*, std::shared_ptr<PolyDataWriterWrapper> writer*/) const
+//{
+//    Grid grid = this->gridKernels[0][0]->grid;
+//    real qval = Qs[GEOMQS][i][qi + 1];
+//    if (qval > 0.0f)
+//    {
+//        int qReverse = grid.d.dir_end - qi;
+//        Vertex dir((real)grid.d.dirs[qReverse * DIMENSION + 0], (real)grid.d.dirs[qReverse* DIMENSION + 1], (real)grid.d.dirs[qReverse * DIMENSION + 2]);
+//        Vertex nodeOnGeometry(startNode + (dir * qval));
+//        std::shared_ptr<Arrow> arrow = ArrowImp::make(startNode, nodeOnGeometry);
+//        trans->transformGridToWorld(arrow);
+//        //writer->addVectorArrow(arrow);
+//    }
+//}
+//
+//Vertex ParallelGridBuilder::getVertex(int matrixIndex) const
+//{
+//    real x, y, z;
+//    this->gridKernels[0][0]->grid.transIndexToCoords(matrixIndex, x, y, z);
+//    return Vertex((real)x, (real)y, (real)z);
+//}
+//
+//int ParallelGridBuilder::getMatrixIndex(int i) const
+//{
+//    int index = (int)Qs[GEOMQS][i][0];
+//    return this->gridKernels[0][0]->grid.matrixIndex[index];
+//}
+//
diff --git a/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.h b/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.h
index bbe8ffe1f..2887aa0d8 100644
--- a/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/ParallelGridBuilder.h
@@ -1,100 +1,100 @@
-#ifndef PARALLEL_GRID_BUILDER_H
-#define PARALLEL_GRID_BUILDER_H
-
-#include "GridGenerator/global.h"
-
-
-#include <vector>
-#include <string>
-#include <memory>
-
-#include "GridBuilder.h"
-
-struct Vertex;
-class GridWrapper;
-class Transformator;
-class ArrowTransformator;
-class PolyDataWriterWrapper;
-
-template <typename T>
-class BoundingBox;
-
-
-class ParallelGridBuilder : public GridBuilder
-{
-public:
-
-    VF_PUBLIC ParallelGridBuilder(GenerationDevice device);
-
-    VF_PUBLIC virtual ~ParallelGridBuilder();
-
-    VF_PUBLIC virtual void addGrid(real length, real width, real high, real delta, std::string distribution, std::shared_ptr<Transformator> trans);
-
-	VF_PUBLIC virtual void meshGeometry(std::string input, int level);
-    VF_PUBLIC virtual void deleteSolidNodes();
-
-	VF_PUBLIC virtual void flood(Vertex &startFlood, int level);
-
-	VF_PUBLIC virtual void writeGridToVTK(std::string output, int level);
-	VF_PUBLIC virtual void writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level);
-
-	VF_PUBLIC virtual std::shared_ptr<GridWrapper> getGridWrapper(int level, int box);
-
-    VF_PUBLIC virtual void createBoundaryConditions();
-
-    VF_PUBLIC virtual unsigned int getNumberOfNodes(unsigned int level) const;;
-    VF_PUBLIC virtual std::vector<std::vector<std::vector<real> > > getQsValues() const;
-
-    VF_PUBLIC virtual int getBoundaryConditionSize(int rb) const;
-    VF_PUBLIC virtual std::vector<std::string> getTypeOfBoundaryConditions() const;
-
-    VF_PUBLIC virtual void getNodeValues(real *xCoords, real *yCoords, real *zCoords, unsigned int *nx, unsigned int *ny, unsigned int *nz, unsigned int *geo, const int level) const;
-    VF_PUBLIC virtual void getDimensions(int &nx, int &ny, int &nz, const int level) const;
-
-    VF_PUBLIC virtual void setQs(real** q27, int* k, int channelSide, unsigned int level) const;
-    VF_PUBLIC virtual void setOutflowValues(real* RhoBC, int* kN, int channelSide, int level) const;
-    VF_PUBLIC virtual void setVelocityValues(real* vx, real* vy, real* vz, int channelSide, int level) const;
-    VF_PUBLIC virtual void setPressValues(real* RhoBC, int* kN, int channelSide, int level) const;
-
-    VF_PUBLIC void writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const;
-
-protected:
-    GenerationDevice device;
-
-    std::vector<std::vector<std::shared_ptr<GridWrapper> > >gridKernels;
-    std::vector<std::shared_ptr<Transformator>> transformators;
-    std::vector<std::vector<BoundingBox<int>> > boxes;
-    std::vector<int> rankTasks;
-    std::vector<std::vector<int> > gridDimensions;
-
-
-    std::vector<std::vector<std::vector<real> > > Qs;
-    std::vector<std::string> channelBoundaryConditions;
-
-    void checkLevel(int level);
-
-protected:
-    virtual void createGridKernels(std::string distribution);
-
-    void setNumberOfNodes(real length, real width, real high, real delta);
-    void printMasterInformation(int nx, int ny, int nz);
-    void setCudaDevice(int rank);
-    void rebuildBoxes();
-    void sendTasks();
-    void receiveTasks();
-    void writeBoxes(std::string name);
-
-protected:
-    void createBCVectors();
-    void addShortQsToVector(int index);
-    void addQsToVector(int index);
-    void fillRBForNode(int x, int y, int z, int index, int direction, int directionSign, int rb);
-
-    int getMatrixIndex(const int i) const;
-    Vertex getVertex(const int matrixIndex) const;
-    void writeArrow(const int i, const int qi, const Vertex& startNode, std::shared_ptr<const ArrowTransformator> trans/*, std::shared_ptr<PolyDataWriterWrapper> writer*/) const;
-
-};
-
-#endif
-
+//#ifndef PARALLEL_GRID_BUILDER_H
+//#define PARALLEL_GRID_BUILDER_H
+//
+//#include "GridGenerator/global.h"
+//
+//
+//#include <vector>
+//#include <string>
+//#include <memory>
+//
+//#include "GridBuilder.h"
+//
+//struct Vertex;
+//class GridWrapper;
+//class Transformator;
+//class ArrowTransformator;
+//class PolyDataWriterWrapper;
+//
+//template <typename T>
+//class BoundingBox;
+//
+//
+//class ParallelGridBuilder : public GridBuilder
+//{
+//public:
+//
+//    VF_PUBLIC ParallelGridBuilder(GenerationDevice device);
+//
+//    VF_PUBLIC virtual ~ParallelGridBuilder();
+//
+//    VF_PUBLIC virtual void addGrid(real length, real width, real high, real delta, std::string distribution, std::shared_ptr<Transformator> trans);
+//
+//	VF_PUBLIC virtual void meshGeometry(std::string input, int level);
+//    VF_PUBLIC virtual void deleteSolidNodes();
+//
+//	VF_PUBLIC virtual void flood(Vertex &startFlood, int level);
+//
+//	VF_PUBLIC virtual void writeGridToVTK(std::string output, int level);
+//	VF_PUBLIC virtual void writeSimulationFiles(std::string output, BoundingBox<int> &nodesDelete, bool writeFilesBinary, int level);
+//
+//	VF_PUBLIC virtual std::shared_ptr<GridWrapper> getGridWrapper(int level, int box);
+//
+//    VF_PUBLIC virtual void createBoundaryConditions();
+//
+//    VF_PUBLIC virtual unsigned int getNumberOfNodes(unsigned int level) const;;
+//    VF_PUBLIC virtual std::vector<std::vector<std::vector<real> > > getQsValues() const;
+//
+//    VF_PUBLIC virtual int getBoundaryConditionSize(int rb) const;
+//    VF_PUBLIC virtual std::vector<std::string> getTypeOfBoundaryConditions() const;
+//
+//    VF_PUBLIC virtual void getNodeValues(real *xCoords, real *yCoords, real *zCoords, unsigned int *nx, unsigned int *ny, unsigned int *nz, unsigned int *geo, const int level) const;
+//    VF_PUBLIC virtual void getDimensions(int &nx, int &ny, int &nz, const int level) const;
+//
+//    VF_PUBLIC virtual void setQs(real** q27, int* k, int channelSide, unsigned int level) const;
+//    VF_PUBLIC virtual void setOutflowValues(real* RhoBC, int* kN, int channelSide, int level) const;
+//    VF_PUBLIC virtual void setVelocityValues(real* vx, real* vy, real* vz, int channelSide, int level) const;
+//    VF_PUBLIC virtual void setPressValues(real* RhoBC, int* kN, int channelSide, int level) const;
+//
+//    VF_PUBLIC void writeArrows(std::string fileName, std::shared_ptr<ArrowTransformator> trans) const;
+//
+//protected:
+//    GenerationDevice device;
+//
+//    std::vector<std::vector<std::shared_ptr<GridWrapper> > >gridKernels;
+//    std::vector<std::shared_ptr<Transformator>> transformators;
+//    std::vector<std::vector<BoundingBox<int>> > boxes;
+//    std::vector<int> rankTasks;
+//    std::vector<std::vector<int> > gridDimensions;
+//
+//
+//    std::vector<std::vector<std::vector<real> > > Qs;
+//    std::vector<std::string> channelBoundaryConditions;
+//
+//    void checkLevel(int level);
+//
+//protected:
+//    virtual void createGridKernels(std::string distribution);
+//
+//    void setNumberOfNodes(real length, real width, real high, real delta);
+//    void printMasterInformation(int nx, int ny, int nz);
+//    void setCudaDevice(int rank);
+//    void rebuildBoxes();
+//    void sendTasks();
+//    void receiveTasks();
+//    void writeBoxes(std::string name);
+//
+//protected:
+//    void createBCVectors();
+//    void addShortQsToVector(int index);
+//    void addQsToVector(int index);
+//    void fillRBForNode(int x, int y, int z, int index, int direction, int directionSign, int rb);
+//
+//    int getMatrixIndex(const int i) const;
+//    Vertex getVertex(const int matrixIndex) const;
+//    void writeArrow(const int i, const int qi, const Vertex& startNode, std::shared_ptr<const ArrowTransformator> trans/*, std::shared_ptr<PolyDataWriterWrapper> writer*/) const;
+//
+//};
+//
+//#endif
+//
diff --git a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
new file mode 100644
index 000000000..008b97ea4
--- /dev/null
+++ b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
@@ -0,0 +1,93 @@
+#include "GridCpuStrategy.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <omp.h>
+#include <vector>
+
+#include <GridGenerator/grid/distributions/Distribution.h>
+#include <GridGenerator/grid/Grid.cuh>
+      
+#include <GridGenerator/geometries/Geometry/Geometry.cuh>
+
+#include <utilities/logger/Logger.h>
+
+void GridCpuStrategy::allocateGridMemory(SPtr<Grid> grid)
+{
+    grid->field = new char[grid->size];
+        
+    grid->neighborIndexX = new int[grid->size];
+    grid->neighborIndexY = new int[grid->size];
+    grid->neighborIndexZ = new int[grid->size];
+        
+    grid->matrixIndex = new unsigned int[grid->size];
+
+
+    unsigned long distributionSize = grid->size * (grid->d.dir_end + 1);
+    real sizeInMB = distributionSize * sizeof(real) / (1024.f*1024.f);
+
+    *logging::out << logging::Logger::LOW << "Allocating " + SSTR(sizeInMB) + " [MB] host memory for distributions.\n";
+
+    grid->d.f = new real[distributionSize](); // automatic initialized with zeros
+}
+
+void GridCpuStrategy::initalNodes(SPtr<Grid> grid)
+{
+#pragma omp parallel for
+    for (unsigned int index = 0; index < grid->size; index++)
+    {
+        grid->setNeighborIndices(index);
+        grid->matrixIndex[index] = index;
+        grid->setFieldEntryToFluid(index);
+    }
+}
+
+void GridCpuStrategy::mesh(SPtr<Grid> grid, Geometry &geom)
+{
+#pragma omp parallel for
+    for (int i = 0; i < geom.size; i++)
+        grid->meshTriangleExact(geom.triangles[i]);
+}
+
+void GridCpuStrategy::deleteSolidNodes(SPtr<Grid> grid)
+{
+    clock_t begin = clock();
+
+    findInvalidNodes(grid);
+    grid->removeInvalidNodes();
+    findNeighborIndices(grid);
+
+    clock_t end = clock();
+    float time = (real)(real(end - begin) / CLOCKS_PER_SEC);
+    *logging::out << logging::Logger::INTERMEDIATE << "time delete solid nodes: " + SSTR(time / 1000) + "sec\n";
+}
+
+void GridCpuStrategy::findInvalidNodes(SPtr<Grid> grid)
+{
+    bool foundInvalidNode = true;
+    while (foundInvalidNode)
+    {
+        foundInvalidNode = false;
+        for (int index = 0; index < grid->size; index++)
+            grid->setInvalidNode(index, foundInvalidNode);
+    }
+}
+
+void GridCpuStrategy::findNeighborIndices(SPtr<Grid> grid)
+{
+    for (int index = 0; index < grid->reducedSize; index++) 
+        grid->findNeighborIndex(index);
+}
+
+void GridCpuStrategy::freeMemory(SPtr<Grid> grid)
+{
+    delete[] grid->field;
+
+    delete[] grid->neighborIndexX;
+    delete[] grid->neighborIndexY;
+    delete[] grid->neighborIndexZ;
+    delete[] grid->matrixIndex;
+
+    delete[] grid->d.f;
+}
+
diff --git a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
new file mode 100644
index 000000000..35e5b2a66
--- /dev/null
+++ b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
@@ -0,0 +1,37 @@
+#ifndef GRID_CPU_STRATEGY_H
+#define GRID_CPU_STRATEGY_H
+
+#include "GridGenerator/global.h"
+
+#include "../GridStrategy.h"
+
+#include "core/PointerDefinitions.h"
+
+
+struct Grid;
+struct Geometry;
+
+class VF_PUBLIC GridCpuStrategy : public GridStrategy
+{
+public:
+	virtual ~GridCpuStrategy() {};
+
+    void allocateGridMemory(SPtr<Grid> grid) override;
+
+    void initalNodes(SPtr<Grid> grid) override;
+    void mesh(SPtr<Grid> grid, Geometry &geom) override;
+
+    void freeMemory(SPtr<Grid> grid) override;
+
+
+    void deleteSolidNodes(SPtr<Grid> grid) override;
+
+    virtual void copyDataFromGPU() {};
+
+protected:
+    void findInvalidNodes(SPtr<Grid> grid);
+    void findNeighborIndices(SPtr<Grid> grid);
+
+};
+
+#endif
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPUTest.cpp b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategyTest.cpp
similarity index 100%
rename from src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPUTest.cpp
rename to src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategyTest.cpp
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperCPU/package.include b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/package.include
similarity index 100%
rename from src/GridGenerator/grid/GridWrapper/GridWrapperCPU/package.include
rename to src/GridGenerator/grid/GridStrategy/GridCpuStrategy/package.include
diff --git a/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
new file mode 100644
index 000000000..eb00ca36c
--- /dev/null
+++ b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
@@ -0,0 +1,247 @@
+#include "GridGpuStrategy.h"
+
+#include "time.h"
+#include "GridGenerator/global.h"
+
+#include <GridGenerator/utilities/cuda/CudaErrorCheck.cu>
+#include <GridGenerator/utilities/Launchparameter/LaunchParameter.cuh>
+
+#include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
+#include <GridGenerator/geometries/Geometry/Geometry.cuh>
+
+#include <GridGenerator/grid/kernel/runGridKernelGPU.cuh>
+#include <GridGenerator/grid/Grid.cuh>
+
+
+#include <utilities/logger/Logger.h>
+#include <helper_cuda.h>
+
+
+void GridGpuStrategy::allocateGridMemory(SPtr<Grid> grid)
+{
+    this->allocDistribution(grid);
+    this->allocField(grid);
+    this->allocMatrixIndicesOnGPU(grid);
+    this->allocNeighborsIndices(grid);
+}
+
+void GridGpuStrategy::initalNodes(SPtr<Grid> grid)
+{
+    float time = runKernelInitalUniformGrid3d(LaunchParameter::make_2D1D_launchParameter(grid->size, 256), *grid.get());
+}
+
+void GridGpuStrategy::mesh(SPtr<Grid> grid, Geometry &geom)
+{
+    *logging::out << logging::Logger::INTERMEDIATE << "start meshing on GPU...\n";
+    allocAndCopyTrianglesToGPU(geom);
+
+    /*---------------------------------------------------------------------------------*/
+    float time = runKernelToMesh(LaunchParameter::make_1D1D_launchParameter(geom.size, 256), *grid.get(), geom);
+    /*---------------------------------------------------------------------------------*/
+    *logging::out << logging::Logger::INTERMEDIATE << "Time GPU build grid: " + SSTR(time / 1000) + "sec\n";
+    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
+
+    freeTrianglesFromGPU(geom);
+}
+
+void GridGpuStrategy::deleteSolidNodes(SPtr<Grid> grid)
+{
+    float time1 = runKernelSetToInvalid(LaunchParameter::make_2D1D_launchParameter(grid->size, 512), *grid.get());
+
+    copyAndFreeFieldFromGPU(grid);
+    copyAndFreeMatrixIndicesFromGPU(grid, grid->size);
+
+    grid->removeInvalidNodes();
+
+    allocAndCopyFieldToGPU(grid);
+    allocAndCopyMatrixIndicesToGPU(grid);
+
+    float time2 = runKernelFindIndices(LaunchParameter::make_2D1D_launchParameter(grid->reducedSize, 256), *grid.get());
+    *logging::out << logging::Logger::INTERMEDIATE << "time delete solid nodes: " + SSTR((time1 + time2) / 1000) + "sec\n";
+}
+
+
+void GridGpuStrategy::freeMemory(SPtr<Grid> grid)
+{
+    delete[] grid->field;
+
+    delete[] grid->neighborIndexX;
+    delete[] grid->neighborIndexY;
+    delete[] grid->neighborIndexZ;
+    delete[] grid->matrixIndex;
+
+    delete[] grid->d.f;
+}
+
+
+void GridGpuStrategy::copyDataFromGPU(SPtr<Grid> grid)
+{
+    copyAndFreeFieldFromGPU(grid);
+    copyAndFreeNeighborsToCPU(grid);
+    copyAndFreeMatrixIndicesFromGPU(grid, grid->reducedSize);
+    copyAndFreeDistributiondFromGPU(grid);
+}
+//
+//void GridWrapperGPU::markNodesToDeleteOutsideOfGeometry()
+//{
+//    int numberOfEdgeNodes = grid.ny * grid.nz;
+//
+//    /*---------------------------------------------------------------------------------*/
+//    float time = runKernelToMarkNodesToDeleteOutsideOfGeometry(LaunchParameter::make_1D1D_launchParameter(numberOfEdgeNodes, 256), grid);
+//    /*---------------------------------------------------------------------------------*/
+//
+//    *logging::out << logging::Logger::INTERMEDIATE << "mark nodes to delete: " + SSTR(time / 1000) + "sec\n";
+//    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
+//}
+
+/*#################################################################################*/
+/*--------------------------------private methods----------------------------------*/
+/*---------------------------------------------------------------------------------*/
+void GridGpuStrategy::allocField(SPtr<Grid> grid)
+{
+    *logging::out << logging::Logger::INTERMEDIATE << "alloc on device for grid field: " + SSTR(grid->size * sizeof(char) / 1000 / 1000) + " MB\n";
+
+    char *field_d;
+    CudaSafeCall(cudaMalloc(&field_d, grid->size * sizeof(char)));
+    grid->field = field_d;
+}
+
+void GridGpuStrategy::allocDistribution(SPtr<Grid> grid)
+{
+    CudaSafeCall(cudaMemcpyToSymbol(DIRECTIONS, grid->d.dirs, grid->d.dir_end * DIMENSION * sizeof(int)));
+    CudaCheckError();
+
+    unsigned long long distributionSize = grid->size * (grid->d.dir_end + 1);
+    unsigned long long size_in_bytes = distributionSize * sizeof(real);
+    real sizeInMB = size_in_bytes / (1024.f*1024.f);
+    *logging::out << logging::Logger::INTERMEDIATE << "Allocating " + SSTR(sizeInMB) + " [MB] device memory for distributions.\n\n";
+
+    checkCudaErrors(cudaMalloc(&grid->d.f, size_in_bytes));
+    CudaCheckError();
+}
+
+void GridGpuStrategy::allocNeighborsIndices(SPtr<Grid> grid)
+{
+    int size_in_bytes_neighbors = grid->size * sizeof(int);
+    int *neighborIndexX, *neighborIndexY, *neighborIndexZ;
+    CudaSafeCall(cudaMalloc(&neighborIndexX, size_in_bytes_neighbors));
+    CudaSafeCall(cudaMalloc(&neighborIndexY, size_in_bytes_neighbors));
+    CudaSafeCall(cudaMalloc(&neighborIndexZ, size_in_bytes_neighbors));
+    grid->neighborIndexX = neighborIndexX;
+    grid->neighborIndexY = neighborIndexY;
+    grid->neighborIndexZ = neighborIndexZ;
+    CudaCheckError();
+}
+
+void GridGpuStrategy::allocMatrixIndicesOnGPU(SPtr<Grid> grid)
+{
+    int size_in_bytes_nodes_reduced = grid->size * sizeof(unsigned int);
+    unsigned int* indices_reduced_d;
+    CudaSafeCall(cudaMalloc(&indices_reduced_d, size_in_bytes_nodes_reduced));
+    grid->matrixIndex = indices_reduced_d;
+    CudaCheckError();
+}
+
+
+void GridGpuStrategy::allocAndCopyTrianglesToGPU(Geometry &geom)
+{
+    *logging::out << logging::Logger::INTERMEDIATE << "start copying triangles ...\n";
+    clock_t begin = clock();
+    int size_in_bytes_triangles = sizeof(Triangle)*geom.size;
+    real sizeInMB = size_in_bytes_triangles / (1024.f*1024.f);
+
+    *logging::out << logging::Logger::INTERMEDIATE << "Allocating " + SSTR(sizeInMB) + " [MB] device memory for triangles.\n\n";
+
+    Triangle *triangles_d;
+    CudaSafeCall(cudaMalloc(&triangles_d, size_in_bytes_triangles));
+    CudaSafeCall(cudaMemcpy(triangles_d, geom.triangles, size_in_bytes_triangles, cudaMemcpyHostToDevice));
+    geom.triangles = triangles_d;
+    CudaCheckError();
+    clock_t end = clock();
+    real time = real(end - begin) / CLOCKS_PER_SEC;
+    *logging::out << logging::Logger::INTERMEDIATE << "time copying triangles: " + SSTR(time) + "s\n";
+    *logging::out << logging::Logger::INTERMEDIATE << "...copying triangles finish!\n\n";
+}
+
+void GridGpuStrategy::freeTrianglesFromGPU(const Geometry &geom)
+{
+    CudaSafeCall(cudaFree(geom.triangles));
+    CudaCheckError();
+}
+
+void GridGpuStrategy::allocAndCopyMatrixIndicesToGPU(SPtr<Grid> grid)
+{
+    int size_in_bytes_nodes_reduced = grid->reducedSize * sizeof(unsigned int);
+    unsigned int* indices_reduced_d;
+    CudaSafeCall(cudaMalloc(&indices_reduced_d, size_in_bytes_nodes_reduced));
+    CudaSafeCall(cudaMemcpy(indices_reduced_d, grid->matrixIndex, size_in_bytes_nodes_reduced, cudaMemcpyHostToDevice));
+    delete[] grid->matrixIndex;
+    grid->matrixIndex = indices_reduced_d;
+    CudaCheckError();
+}
+
+void GridGpuStrategy::allocAndCopyFieldToGPU(SPtr<Grid> grid)
+{
+    int size_in_bytes_grid = grid->size * sizeof(char);
+    char* field_d;
+    CudaSafeCall(cudaMalloc(&field_d, size_in_bytes_grid));
+    CudaSafeCall(cudaMemcpy(field_d, grid->field, size_in_bytes_grid, cudaMemcpyHostToDevice));
+    delete[] grid->field;
+    grid->field = field_d;
+    CudaCheckError();
+}
+
+void GridGpuStrategy::copyAndFreeFieldFromGPU(SPtr<Grid> grid)
+{
+    char *field_h = new char[grid->size];
+    CudaSafeCall(cudaMemcpy(field_h, grid->field, grid->size * sizeof(char), cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaFree(grid->field));
+    CudaCheckError();
+    grid->field = field_h;
+}
+
+void GridGpuStrategy::copyAndFreeDistributiondFromGPU(SPtr<Grid> grid)
+{
+    unsigned long long distributionSize = grid->size * (grid->d.dir_end + 1);
+    real *f_host = new real[distributionSize];
+    CudaSafeCall(cudaMemcpy(f_host, grid->d.f, distributionSize * sizeof(real), cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaFree(grid->d.f));
+    CudaCheckError();
+    grid->d.f = f_host;
+}
+
+
+
+void GridGpuStrategy::copyAndFreeNeighborsToCPU(SPtr<Grid> grid)
+{
+    int size_in_bytes_neighbors = grid->size * sizeof(int);
+    int *neighborIndexX_h, *neighborIndexY_h, *neighborIndexZ_h;
+    neighborIndexX_h = new int[grid->size];
+    neighborIndexY_h = new int[grid->size];
+    neighborIndexZ_h = new int[grid->size];
+
+    CudaSafeCall(cudaMemcpy(neighborIndexX_h, grid->neighborIndexX, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaMemcpy(neighborIndexY_h, grid->neighborIndexY, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaMemcpy(neighborIndexZ_h, grid->neighborIndexZ, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaFree(grid->neighborIndexX));
+    CudaSafeCall(cudaFree(grid->neighborIndexY));
+    CudaSafeCall(cudaFree(grid->neighborIndexZ));
+
+    grid->neighborIndexX = neighborIndexX_h;
+    grid->neighborIndexY = neighborIndexY_h;
+    grid->neighborIndexZ = neighborIndexZ_h;
+    CudaCheckError();
+}
+
+void GridGpuStrategy::copyAndFreeMatrixIndicesFromGPU(SPtr<Grid> grid, int size)
+{
+    int size_in_bytes_nodes_reduced = size * sizeof(unsigned int);
+    unsigned int *indices_reduced_h = new unsigned int[size];
+    CudaSafeCall(cudaMemcpy(indices_reduced_h, grid->matrixIndex, size_in_bytes_nodes_reduced, cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaFree(grid->matrixIndex));
+    grid->matrixIndex = indices_reduced_h;
+    CudaCheckError();
+}
+
+
+
diff --git a/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h
new file mode 100644
index 000000000..10867957c
--- /dev/null
+++ b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h
@@ -0,0 +1,53 @@
+#ifndef GRID_GPU_STRATEGY_H
+#define GRID_GPU_STRATEGY_H
+
+#include <VirtualFluidsDefinitions.h>
+
+#include "../GridStrategy.h"
+
+template <class T>
+class BoundingBox;
+struct Geometry;
+
+class VF_PUBLIC GridGpuStrategy : public GridStrategy
+{
+public:
+    virtual ~GridGpuStrategy() {};
+
+    void allocateGridMemory(SPtr<Grid> grid) override;
+
+    void initalNodes(SPtr<Grid> grid) override;
+    void mesh(SPtr<Grid> grid, Geometry &geom) override;
+
+    void freeMemory(SPtr<Grid> grid) override;
+
+
+    void deleteSolidNodes(SPtr<Grid> grid) override;
+
+
+    virtual void copyDataFromGPU(SPtr<Grid> grid);
+
+	//void markNodesToDeleteOutsideOfGeometry();
+
+private:
+    void allocField(SPtr<Grid> grid);
+    void allocDistribution(SPtr<Grid> grid);
+    void allocNeighborsIndices(SPtr<Grid> grid);
+    void allocMatrixIndicesOnGPU(SPtr<Grid> grid);
+
+    void allocAndCopyTrianglesToGPU(Geometry &geom);
+    void freeTrianglesFromGPU(const Geometry &geom);
+
+
+    void allocAndCopyMatrixIndicesToGPU(SPtr<Grid> grid);
+
+    void allocAndCopyFieldToGPU(SPtr<Grid> grid);
+
+    void copyAndFreeFieldFromGPU(SPtr<Grid> grid);
+    void copyAndFreeDistributiondFromGPU(SPtr<Grid> grid);
+
+    void copyAndFreeNeighborsToCPU(SPtr<Grid> grid);
+    void copyAndFreeMatrixIndicesFromGPU(SPtr<Grid> grid, int size);
+};
+
+#endif
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPUTest.cpp b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategyTest.cpp
similarity index 100%
rename from src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPUTest.cpp
rename to src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategyTest.cpp
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/package.include b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/package.include
similarity index 100%
rename from src/GridGenerator/grid/GridWrapper/GridWrapperGPU/package.include
rename to src/GridGenerator/grid/GridStrategy/GridGpuStrategy/package.include
diff --git a/src/GridGenerator/grid/GridStrategy/GridStrategy.h b/src/GridGenerator/grid/GridStrategy/GridStrategy.h
new file mode 100644
index 000000000..29140f7f7
--- /dev/null
+++ b/src/GridGenerator/grid/GridStrategy/GridStrategy.h
@@ -0,0 +1,30 @@
+#ifndef GRID_STRATEGY_H
+#define GRID_STRATEGY_H
+
+#include "core/PointerDefinitions.h"
+
+struct Vertex;
+struct Geometry;
+struct Grid;
+
+class GridStrategy
+{
+public:
+    virtual ~GridStrategy() {};
+
+    virtual void allocateGridMemory(SPtr<Grid> grid) = 0;
+
+    virtual void initalNodes(SPtr<Grid> grid) = 0;
+    virtual void mesh(SPtr<Grid> grid, Geometry &geom) = 0;
+
+    virtual void deleteSolidNodes(SPtr<Grid> grid) = 0;
+
+    virtual void freeMemory(SPtr<Grid> grid) = 0;
+
+
+    virtual void copyDataFromGPU() = 0;
+
+
+};
+
+#endif
diff --git a/src/GridGenerator/grid/GridWrapper/package.include b/src/GridGenerator/grid/GridStrategy/package.include
similarity index 100%
rename from src/GridGenerator/grid/GridWrapper/package.include
rename to src/GridGenerator/grid/GridStrategy/package.include
diff --git a/src/GridGenerator/grid/GridTest.cpp b/src/GridGenerator/grid/GridTest.cpp
index 0b8f0c72b..ef6d6a8d2 100644
--- a/src/GridGenerator/grid/GridTest.cpp
+++ b/src/GridGenerator/grid/GridTest.cpp
@@ -5,6 +5,7 @@
 #include <GridGenerator/geometries/Vertex/Vertex.cuh>
 #include <GridGenerator/geometries/Triangle/Triangle.cuh>
 #include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
+#include "GridStrategy/GridCpuStrategy/GridCpuStrategy.h"
 
 
 std::vector<Vertex> getPointsInBoundingBox(Triangle t, real delta)
@@ -207,15 +208,35 @@ TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXZisFluid_ItShouldBeAStopperN
 
 TEST(GridTest, transRealCoordsToIndex)
 {
-    Grid grid(0.0, 0.0, 0.0, 10.0, 10.0, 10.0, 0.5, Distribution());
+    SPtr<GridCpuStrategy> gridStrategy(new GridCpuStrategy());
+
+    SPtr<Grid> grid = Grid::getNewInstance(0, 0, 0, 5, 5, 5, 0.5, gridStrategy, DistributionHelper::getDistribution27());
+
 
     Vertex v(1.5, 0.0, 0.0);
 
-    unsigned int index = grid.transCoordToIndex(v);
+    unsigned int index = grid->transCoordToIndex(v);
 
     EXPECT_THAT(index, testing::Eq(3));
 
     real x, y, z;
-    grid.transIndexToCoords(index, x,y,z );
+    grid->transIndexToCoords(index, x,y,z );
+
+}
+
+TEST(GridTest, transNegativeCoordToIndex)
+{
+    SPtr<GridCpuStrategy> gridStrategy(new GridCpuStrategy());
+
+    SPtr<Grid> grid = Grid::getNewInstance(-1, 0, 0, 5, 5, 5, 0.5, gridStrategy, DistributionHelper::getDistribution27());
+
+    Vertex v(0.0, 0.0, 0.0);
+
+    unsigned int index = grid->transCoordToIndex(v);
+
+    EXPECT_THAT(index, testing::Eq(2));
+
+    real x, y, z;
+    grid->transIndexToCoords(index, x, y, z);
 
 }
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapper.cpp b/src/GridGenerator/grid/GridWrapper/GridWrapper.cpp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapper.h b/src/GridGenerator/grid/GridWrapper/GridWrapper.h
deleted file mode 100644
index 94700f5a0..000000000
--- a/src/GridGenerator/grid/GridWrapper/GridWrapper.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef GridKernel_H
-#define GridKernel_H
-
-#include "GridGenerator/global.h"
-
-
-#include <string>
-#include <GridGenerator/grid/Grid.cuh>
-
-struct Vertex;
-struct Geometry;
-
-class VF_PUBLIC GridWrapper
-{
-public:
-    virtual ~GridWrapper() {};
-
-    virtual void meshGrid(Geometry &geom) = 0;
-    virtual void deleteSolidNodes() = 0;
-    virtual void floodFill(const Vertex &vec) = 0;
-    virtual void copyDataFromGPU() = 0;
-
-    Grid grid;
-
-private:
-	virtual void allocDistribution() = 0;
-	virtual void allocField() = 0;
-};
-
-#endif
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h b/src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h
deleted file mode 100644
index 3946754c2..000000000
--- a/src/GridGenerator/grid/GridWrapper/GridWrapperCPU/GridWrapperCPU.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef GridKernelCPU_H
-#define GridKernelCPU_H
-
-
-#include "GridGenerator/global.h"
-#include "../GridWrapper.h"
-
-#include <string>
-
-
-struct Triangle;
-struct Vertex;
-
-template <class T>
-class BoundingBox;
-
-class VF_PUBLIC GridWrapperCPU : public GridWrapper
-{
-public:
-    GridWrapperCPU(){};
-    GridWrapperCPU(BoundingBox<int> &channel, std::string d3Qxx);
-    GridWrapperCPU(uint minX, uint minY, uint minZ, uint maxX, uint maxY, uint maxZ, std::string d3Qxx);
-
-	virtual ~GridWrapperCPU();
-
-    virtual void meshGrid(Geometry &geom);
-    virtual void deleteSolidNodes();
-    virtual void floodFill(const Vertex &vec);
-    virtual void copyDataFromGPU() {};
-
-private:
-	real initalUniformGrid3d();
-	void initialGridNodes();
-	virtual void allocDistribution();
-	virtual void allocField();
-	void runMeshing(const Geometry &geom);
-
-    void findInvalidNodes();
-    void findNeighborIndices();
-};
-
-#endif
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.cpp b/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.cpp
deleted file mode 100644
index b7b9a2972..000000000
--- a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-#include "GridWrapperGPU.h"
-
-#include "time.h"
-#include "GridGenerator/global.h"
-
-#include <GridGenerator/utilities/cuda/CudaErrorCheck.cu>
-#include <GridGenerator/utilities/Launchparameter/LaunchParameter.cuh>
-
-#include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
-#include <GridGenerator/geometries/Geometry/Geometry.cuh>
-
-#include <GridGenerator/grid/kernel/runGridKernelGPU.cuh>
-
-
-#include <utilities/logger/Logger.h>
-#include <helper_cuda.h>
-
-
-GridWrapperGPU::GridWrapperGPU(BoundingBox<int> &channel, std::string d3Qxx)
-{
-    initalField(channel, d3Qxx);
-}
-
-GridWrapperGPU::GridWrapperGPU(uint minX, uint minY, uint minZ, uint maxX, uint maxY, uint maxZ, std::string d3Qxx)
-{
-}
-
-GridWrapperGPU::~GridWrapperGPU()
-{
-    delete[] this->grid.field;
-    delete[] this->grid.d.f;
-}
-
-void GridWrapperGPU::meshGrid(Geometry &geom)
-{
-    *logging::out << logging::Logger::INTERMEDIATE << "start meshing on GPU...\n";
-    allocAndCopyTrianglesToGPU(geom);
-
-    /*---------------------------------------------------------------------------------*/
-    float time = runKernelToMesh(LaunchParameter::make_1D1D_launchParameter(geom.size, 256), grid, geom);
-    /*---------------------------------------------------------------------------------*/
-    *logging::out << logging::Logger::INTERMEDIATE << "Time GPU build grid: " + SSTR(time / 1000) + "sec\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
-
-    freeTrianglesFromGPU(geom);
-}
-
-void GridWrapperGPU::deleteSolidNodes()
-{
-    float time1 = runKernelSetToInvalid(LaunchParameter::make_2D1D_launchParameter(grid.size, 512), grid);
-
-    copyAndFreeFieldFromGPU();
-    copyAndFreeMatrixIndicesFromGPU(grid.size);
-
-    grid.removeInvalidNodes();
-
-    allocAndCopyFieldToGPU();
-    allocAndCopyMatrixIndicesToGPU();
-    
-    float time2 = runKernelFindIndices(LaunchParameter::make_2D1D_launchParameter(grid.reducedSize, 256), grid);
-    *logging::out << logging::Logger::INTERMEDIATE << "time delete solid nodes: " + SSTR((time1+time2) / 1000) + "sec\n";
-    
-}
-
-void GridWrapperGPU::floodFill(const Vertex &vec)
-{
-
-}
-
-void GridWrapperGPU::copyDataFromGPU()
-{
-    copyAndFreeFieldFromGPU();
-    copyAndFreeNeighborsToCPU();
-    copyAndFreeMatrixIndicesFromGPU(grid.reducedSize);
-    copyAndFreeDistributiondFromGPU();
-}
-
-void GridWrapperGPU::markNodesToDeleteOutsideOfGeometry()
-{
-    int numberOfEdgeNodes = grid.ny * grid.nz;
-
-    /*---------------------------------------------------------------------------------*/
-    float time = runKernelToMarkNodesToDeleteOutsideOfGeometry(LaunchParameter::make_1D1D_launchParameter(numberOfEdgeNodes, 256), grid);
-    /*---------------------------------------------------------------------------------*/
-
-    *logging::out << logging::Logger::INTERMEDIATE << "mark nodes to delete: " + SSTR(time / 1000) + "sec\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
-}
-
-/*#################################################################################*/
-/*--------------------------------private methods----------------------------------*/
-/*---------------------------------------------------------------------------------*/
-void GridWrapperGPU::initalField(BoundingBox<int> &box, std::string d3Qxx)
-{
-    int nx = box.maxX - box.minX;
-    int ny = box.maxY - box.minY;
-    int nz = box.maxZ - box.minZ;
-    this->grid = Grid(NULL, box.minX, box.minY, box.minZ, nx, ny, nz, DistributionHelper::getDistribution(d3Qxx));
-    this->allocDistribution();
-    this->allocField();
-    this->allocMatrixIndicesOnGPU();
-    this->allocNeighborsIndices();
-
-    /*---------------------------------------------------------------------------------*/
-    float time = runKernelInitalUniformGrid3d(LaunchParameter::make_2D1D_launchParameter(grid.size, 256), grid);
-    /*---------------------------------------------------------------------------------*/
-
-    *logging::out << logging::Logger::INTERMEDIATE << "Time GPU initial field: " + SSTR(time / 1000) + "sec\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
-}
-
-void GridWrapperGPU::allocField()
-{
-    *logging::out << logging::Logger::INTERMEDIATE << "-------------------------------------------\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "Initial field with fluid: \n";
-    *logging::out << logging::Logger::INTERMEDIATE << "Field offset: " + SSTR(grid.startX) + ", " + SSTR(grid.startY) + ", " + SSTR(grid.startZ) + "\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "Field dimension: " + SSTR(grid.nx) + ", " + SSTR(grid.ny) + ", " + SSTR(grid.nz) + "\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "Number of Nodes: " + SSTR(grid.size) + "\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "alloc on device for grid: " + SSTR(grid.size * sizeof(char) / 1000 / 1000) + " MB\n";
-
-    char *field_d;
-    CudaSafeCall(cudaMalloc(&field_d, grid.size * sizeof(char)));
-    grid.field = field_d;
-}
-
-void GridWrapperGPU::allocAndCopyTrianglesToGPU(Geometry &geom)
-{
-    *logging::out << logging::Logger::INTERMEDIATE << "start copying triangles ...\n";
-    clock_t begin = clock();
-    int size_in_bytes_triangles = sizeof(Triangle)*geom.size;
-    real sizeInMB = size_in_bytes_triangles / (1024.f*1024.f);
-
-    *logging::out << logging::Logger::INTERMEDIATE << "Allocating " + SSTR(sizeInMB) + " [MB] device memory for triangles.\n\n";
-
-    Triangle *triangles_d;
-    CudaSafeCall(cudaMalloc(&triangles_d, size_in_bytes_triangles));
-    CudaSafeCall(cudaMemcpy(triangles_d, geom.triangles, size_in_bytes_triangles, cudaMemcpyHostToDevice));
-    geom.triangles = triangles_d;
-    CudaCheckError();
-    clock_t end = clock();
-    real time = real(end - begin) / CLOCKS_PER_SEC;
-    *logging::out << logging::Logger::INTERMEDIATE << "time copying triangles: " + SSTR(time) + "s\n";
-    *logging::out << logging::Logger::INTERMEDIATE << "...copying triangles finish!\n\n";
-}
-
-
-void GridWrapperGPU::allocDistribution()
-{
-    CudaSafeCall(cudaMemcpyToSymbol(DIRECTIONS, grid.d.dirs, grid.d.dir_end * DIMENSION * sizeof(int)));
-    CudaCheckError();
-
-    unsigned long long distributionSize = grid.size * (grid.d.dir_end + 1);
-    unsigned long long size_in_bytes = distributionSize * sizeof(real);
-    real sizeInMB = size_in_bytes / (1024.f*1024.f);
-    *logging::out << logging::Logger::INTERMEDIATE << "Allocating " + SSTR(sizeInMB) + " [MB] device memory for distributions.\n\n";
-
-    checkCudaErrors(cudaMalloc(&grid.d.f, size_in_bytes));
-    CudaCheckError();
-}
-
-void GridWrapperGPU::allocNeighborsIndices()
-{
-    int size_in_bytes_neighbors = grid.size * sizeof(int);
-    int *neighborIndexX, *neighborIndexY, *neighborIndexZ;
-    CudaSafeCall(cudaMalloc(&neighborIndexX, size_in_bytes_neighbors));
-    CudaSafeCall(cudaMalloc(&neighborIndexY, size_in_bytes_neighbors));
-    CudaSafeCall(cudaMalloc(&neighborIndexZ, size_in_bytes_neighbors));
-    grid.neighborIndexX = neighborIndexX;
-    grid.neighborIndexY = neighborIndexY;
-    grid.neighborIndexZ = neighborIndexZ;
-    CudaCheckError();
-}
-
-void GridWrapperGPU::allocMatrixIndicesOnGPU()
-{
-    int size_in_bytes_nodes_reduced = grid.size * sizeof(unsigned int);
-    unsigned int* indices_reduced_d;
-    CudaSafeCall(cudaMalloc(&indices_reduced_d, size_in_bytes_nodes_reduced));
-    grid.matrixIndex = indices_reduced_d;
-    CudaCheckError();
-}
-
-
-void GridWrapperGPU::allocAndCopyMatrixIndicesToGPU()
-{
-    int size_in_bytes_nodes_reduced = grid.reducedSize * sizeof(unsigned int);
-    unsigned int* indices_reduced_d;
-    CudaSafeCall(cudaMalloc(&indices_reduced_d, size_in_bytes_nodes_reduced));
-    CudaSafeCall(cudaMemcpy(indices_reduced_d, grid.matrixIndex, size_in_bytes_nodes_reduced, cudaMemcpyHostToDevice));
-    delete[] grid.matrixIndex;
-    grid.matrixIndex = indices_reduced_d;
-    CudaCheckError();
-}
-
-void GridWrapperGPU::allocAndCopyFieldToGPU()
-{
-    int size_in_bytes_grid = grid.size * sizeof(char);
-    char* field_d;
-    CudaSafeCall(cudaMalloc(&field_d, size_in_bytes_grid));
-    CudaSafeCall(cudaMemcpy(field_d, grid.field, size_in_bytes_grid, cudaMemcpyHostToDevice));
-    delete[] grid.field;
-    grid.field = field_d;
-    CudaCheckError();
-}
-
-void GridWrapperGPU::copyAndFreeFieldFromGPU()
-{
-    char *field_h = new char[grid.size];
-    CudaSafeCall(cudaMemcpy(field_h, grid.field, grid.size * sizeof(char), cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaFree(grid.field));
-    CudaCheckError();
-    grid.field = field_h;
-}
-
-void GridWrapperGPU::copyAndFreeDistributiondFromGPU()
-{
-    unsigned long long distributionSize = grid.size * (grid.d.dir_end + 1);
-    real *f_host = new real[distributionSize];
-    CudaSafeCall(cudaMemcpy(f_host, grid.d.f, distributionSize * sizeof(real), cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaFree(grid.d.f));
-    CudaCheckError();
-    grid.d.f = f_host;
-}
-
-
-void GridWrapperGPU::freeTrianglesFromGPU(const Geometry &geom)
-{
-    CudaSafeCall(cudaFree(geom.triangles));
-    CudaCheckError();
-}
-
-void GridWrapperGPU::copyAndFreeNeighborsToCPU()
-{
-    int size_in_bytes_neighbors = grid.size * sizeof(int);
-    int *neighborIndexX_h, *neighborIndexY_h, *neighborIndexZ_h;
-    neighborIndexX_h = new int[grid.size];
-    neighborIndexY_h = new int[grid.size];
-    neighborIndexZ_h = new int[grid.size];
-
-    CudaSafeCall(cudaMemcpy(neighborIndexX_h, grid.neighborIndexX, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaMemcpy(neighborIndexY_h, grid.neighborIndexY, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaMemcpy(neighborIndexZ_h, grid.neighborIndexZ, size_in_bytes_neighbors, cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaFree(grid.neighborIndexX));
-    CudaSafeCall(cudaFree(grid.neighborIndexY));
-    CudaSafeCall(cudaFree(grid.neighborIndexZ));
-
-    grid.neighborIndexX = neighborIndexX_h;
-    grid.neighborIndexY = neighborIndexY_h;
-    grid.neighborIndexZ = neighborIndexZ_h;
-    CudaCheckError();
-}
-
-void GridWrapperGPU::copyAndFreeMatrixIndicesFromGPU(int size)
-{
-    int size_in_bytes_nodes_reduced = size * sizeof(unsigned int);
-    unsigned int *indices_reduced_h = new unsigned int[size];
-    CudaSafeCall(cudaMemcpy(indices_reduced_h, grid.matrixIndex, size_in_bytes_nodes_reduced, cudaMemcpyDeviceToHost));
-    CudaSafeCall(cudaFree(grid.matrixIndex));
-    grid.matrixIndex = indices_reduced_h;
-    CudaCheckError();
-}
-
-
-
diff --git a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h b/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h
deleted file mode 100644
index 61cfc7a2e..000000000
--- a/src/GridGenerator/grid/GridWrapper/GridWrapperGPU/GridWrapperGPU.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef GridKernelGPU_H
-#define GridKernelGPU_H
-
-
-
-#include <string>
-#include "../GridWrapper.h"
-
-template <class T>
-class BoundingBox;
-struct Geometry;
-
-class VF_PUBLIC GridWrapperGPU : public GridWrapper
-{
-public:
-    GridWrapperGPU(){};
-    GridWrapperGPU(BoundingBox<int> &box, std::string d3Qxx);
-    GridWrapperGPU(uint minX, uint minY, uint minZ, uint maxX, uint maxY, uint maxZ, std::string d3Qxx);
-    virtual ~GridWrapperGPU();
-
-    virtual void meshGrid(Geometry &geom);
-    virtual void deleteSolidNodes();
-    virtual void floodFill(const Vertex &vec);
-    virtual void copyDataFromGPU();
-
-	void markNodesToDeleteOutsideOfGeometry();
-
-private:
-	void initalField(BoundingBox<int> &box, std::string direction);
-	void allocField();
-	void allocDistribution();
-    void allocNeighborsIndices();
-    void allocAndCopyMatrixIndicesToGPU();
-    void allocMatrixIndicesOnGPU();
-
-    void allocAndCopyTrianglesToGPU(Geometry &geom);
-    void allocAndCopyFieldToGPU();
-
-    void copyAndFreeFieldFromGPU();
-    void copyAndFreeDistributiondFromGPU();
-    void freeTrianglesFromGPU(const Geometry &geom);
-
-    void copyAndFreeNeighborsToCPU();
-    void copyAndFreeMatrixIndicesFromGPU(int size);
-};
-
-#endif
diff --git a/src/GridGenerator/grid/kernel/runGridKernelGPU.cu b/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
index 32d0d09e7..8686a8f9f 100644
--- a/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
+++ b/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
@@ -42,7 +42,7 @@ GLOBAL void runMeshing(Grid grid, const Geometry geom)
 {
 	unsigned int i = LaunchParameter::getGlobalIdx_1D_1D();
 	if (i < geom.size)
-		grid.meshTriangle(geom.triangles[i]);
+		grid.meshTriangleExact(geom.triangles[i]);
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
index 8297282c0..ead24b1b8 100644
--- a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
+++ b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
@@ -13,7 +13,6 @@
 #include <GridGenerator/geometries/Vertex/Vertex.cuh>
 
 #include <GridGenerator/grid/GridBuilder/GridBuilder.h>
-#include <GridGenerator/grid/GridWrapper/GridWrapper.h>
 
 
 /*#################################################################################*/
@@ -121,7 +120,7 @@ void SimulationFileWriter::writeLevelAndLevelSize(int sizeCoords, std::vector<st
 
 void SimulationFileWriter::writeCoordsNeighborsGeo(const int& i, bool binaer, std::shared_ptr<GridBuilder> builder, std::shared_ptr<Transformator> trans)
 {
-    Grid grid = builder->getGridWrapper(0, 0)->grid;
+    Grid grid = *builder->getGrid(0, 0).get();
     int index = grid.matrixIndex[i];
 
     int type = grid.field[index] == SOLID ? 16 : 1;
diff --git a/src/core/PointerDefinitions.h b/src/core/PointerDefinitions.h
index 687dbfefe..9305969a2 100644
--- a/src/core/PointerDefinitions.h
+++ b/src/core/PointerDefinitions.h
@@ -20,4 +20,7 @@ using UPtr = std::unique_ptr<T>;
 template <class T>
 using RPtr = T*;
 
+template <class T>
+using enableSharedFromThis = std::enable_shared_from_this<T>;
+
 #endif
diff --git a/targets/apps/HULC/main.cpp b/targets/apps/HULC/main.cpp
index 3871a1606..703c3facb 100644
--- a/targets/apps/HULC/main.cpp
+++ b/targets/apps/HULC/main.cpp
@@ -18,7 +18,8 @@
 #include "grid/GridBuilder/LevelGridBuilder.h"
 #include "utilities/transformator/TransformatorImp.h"
 #include "io/GridVTKWriter/GridVTKWriter.h"
-#include "grid/GridWrapper/GridWrapper.h"
+#include "grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h"
+#include "grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h"
 #include "io/SimulationFileWriter/SimulationFileWriter.h"
 #include "grid/GridBuilder/LevelGridBuilder.h"
 #include "grid/GridBuilder/ParallelGridBuilder.h"
@@ -229,26 +230,17 @@ void setParameters(std::shared_ptr<Parameter> para, std::unique_ptr<input::Input
 
 void multipleLevel(const std::string& configPath)
 {
-    Grid grid(35, 3, -5, 70, 40, 25, 0.5, Distribution());
+    SPtr<GridCpuStrategy> gridStrategy(new GridCpuStrategy());
 
-    for (unsigned int index = 0; index < grid.size; index++)
-    {
-        grid.setNeighborIndices(index);
-        grid.matrixIndex[index] = index;
-        grid.setFieldEntryToFluid(index);
-    }
+    SPtr<Grid> grid = Grid::getNewInstance(35, 3, -5, 70, 40, 25, 0.25, gridStrategy, DistributionHelper::getDistribution27());
 
-    //grid.field[grid.transCoordToIndex(30, 10, 20)] = 11;
-    //real x, y, z;
-    //grid.transIndexToCoords(grid.transCoordToIndex(30, 10, 20), x, y, z);
 
-    Geometry* geometry = new Geometry("D:/GRIDGENERATION/STL/circleBinaer.stl");
-    for (int i = 0; i < geometry->size; i++)
-        grid.meshTriangleExact(geometry->triangles[i]);
-    delete geometry;
+    Geometry geometry = Geometry("D:/GRIDGENERATION/STL/circleBinaer.stl");
+    grid->mesh(geometry);
 
+    GridVTKWriter::writeGridToVTK(*grid.get(), "D:/GRIDGENERATION/gridTest");
 
-    GridVTKWriter::writeGridToVTK(grid, "D:/GRIDGENERATION/gridTest");
+    grid->freeMemory();
 
     //SPtr<Parameter> para = Parameter::make();
     //SPtr<GridProvider> gridGenerator = GridProvider::makeGridGenerator(builder, para);
@@ -269,7 +261,7 @@ void multipleLevel(const std::string& configPath)
 
 void simulate(const std::string& configPath)
 {
-    SPtr<ParallelGridBuilder> builder(new ParallelGridBuilder(GridBuilder::GenerationDevice::CPU));
+    SPtr<LevelGridBuilder> builder(new LevelGridBuilder(GridBuilder::GenerationDevice::CPU));
 
 
     SPtr<Parameter> para = Parameter::make();
@@ -286,15 +278,15 @@ void simulate(const std::string& configPath)
     setParameters(para, input);
 
     SPtr<Transformator> trans(new TransformatorImp());
-    builder->addGrid(para->getGridX()[0], para->getGridY()[0], para->getGridZ()[0], 1.0, "D3Q27", trans);
+    //builder->addGrid(para->getGridX()[0], para->getGridY()[0], para->getGridZ()[0], 1.0, "D3Q27", trans);
 
     SPtr<Transformator> transRefine1(new TransformatorImp(para->getDistX()[1], para->getDistY()[1], para->getDistZ()[1], 0.5));
-    builder->addGrid(para->getGridX()[1], para->getGridY()[1], para->getGridZ()[1], 1.0, "D3Q27", transRefine1);
+    //builder->addGrid(para->getGridX()[1], para->getGridY()[1], para->getGridZ()[1], 1.0, "D3Q27", transRefine1);
 
-    builder->getGridWrapper(0, 0)->copyDataFromGPU();
-    builder->getGridWrapper(1, 0)->copyDataFromGPU();
+    //builder->getGridWrapper(0, 0)->copyDataFromGPU();
+    //builder->getGridWrapper(1, 0)->copyDataFromGPU();
 
-    GridVTKWriter::writeSparseGridToVTK(builder->getGridWrapper(0, 0)->grid, "D:/GRIDGENERATION/couplingVF/periodicTaylor/testFile", trans);
+    //GridVTKWriter::writeSparseGridToVTK(builder->getGridWrapper(0, 0)->grid, "D:/GRIDGENERATION/couplingVF/periodicTaylor/testFile", trans);
     SimulationFileWriter::writeSimulationFiles("D:/GRIDGENERATION/couplingVF/periodicTaylor/simuFiles/", builder, false, trans);
 
     Simulation sim;
-- 
GitLab