diff --git a/src/GridGenerator/grid/Grid.cu b/src/GridGenerator/grid/Grid.cu
index 349a79be0d486b646f9d2a50a026da34607b0a15..70f11373d0e5fa83f91071599823ce111be29ba1 100644
--- a/src/GridGenerator/grid/Grid.cu
+++ b/src/GridGenerator/grid/Grid.cu
@@ -9,6 +9,7 @@
 
 
 #include <GridGenerator/utilities/math/CudaMath.cuh>
+#include "distributions/Distribution.h"
 
 #include <GridGenerator/geometries/Vertex/Vertex.cuh>
 #include <GridGenerator/geometries/Triangle/Triangle.cuh>
@@ -24,22 +25,24 @@
 
 CONSTANT int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
-HOST Grid::Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution &d) 
-: startX(startX), startY(startY), startZ(startZ), endX(endX), endY(endY), endZ(endZ), delta(delta), gridStrategy(gridStrategy), 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 distribution)
+    : startX(startX), startY(startY), startZ(startZ), endX(endX), endY(endY), endZ(endZ), delta(delta), field(nullptr), distribution(distribution),
+    gridInterface(nullptr), neighborIndexX(nullptr), neighborIndexY(nullptr), neighborIndexZ(nullptr), matrixIndex(nullptr), gridStrategy(gridStrategy)
 {
     const real length = endX - startX;
     const real width = endY - startY;
     const real height = endZ - startZ;
 
-    nx = int((length + delta) / delta);
-    ny = int((width  + delta) / delta);
-    nz = int((height + delta) / delta);
+    nx = int((length + delta) / delta) + 1; // +1 stopper node
+    ny = int((width + delta) / delta) + 1; // +1 stopper node
+    nz = int((height + delta) / delta) + 1; // +1 stopper node
 
     this->size = nx * ny * nz;
     this->reducedSize = size;
 }
 
-HOST SPtr<Grid> Grid::makeShared(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution &d)
+HOST SPtr<Grid> Grid::makeShared(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));
 
@@ -58,18 +61,17 @@ HOST SPtr<Grid> Grid::makeShared(real startX, real startY, real startZ, real end
     return grid;
 }
 
-HOST Grid::Grid(){};
-
+HOST Grid::Grid()
+{
+    printf("Constructor\n");
+    this->print();
+};
 
-HOST Grid::Grid(char *field, int startX, int startY, int startZ, int eX, int eY, int eZ, Distribution &d)
-    : field(field), startX(startX), startY(startY), startZ(startZ), endX(eX), endY(eY), endZ(eZ), d(d)
+HOST Grid::~Grid()
 {
-    nx = eX;
-    ny = eY;
-    nz = eZ;
-    this->size = eX * eY * eZ;
-    this->reducedSize = size;
-}
+    printf("Destructor\n");
+    this->print();
+};
 
 HOST void Grid::mesh(Geometry &geometry)
 {
@@ -95,6 +97,9 @@ HOST void Grid::removeOverlapNodes(SPtr<Grid> finerGrid)
 
 HOSTDEVICE void Grid::setOverlapNodeToInvalid(uint index, const Grid& finerGrid)
 {
+    gridInterface->findCF(index, this, &finerGrid);
+    gridInterface->findFC(index, this, &finerGrid);
+
     if (this->isInside(index, finerGrid))
         this->setFieldEntryToInvalid(index);
 }
@@ -107,9 +112,6 @@ HOSTDEVICE bool Grid::isInside(uint index, const Grid& finerGrid)
     const real overlapWithStopper = 3 * this->delta;
     const real overlap = 2 * this->delta;
 
-    gridInterface->findCF(index, this, &finerGrid);
-    gridInterface->findFC(index, this, &finerGrid);
-
     return 
         (x > finerGrid.startX + overlapWithStopper && x < finerGrid.endX - overlap) &&
         (y > finerGrid.startY + overlapWithStopper && y < finerGrid.endY - overlap) &&
@@ -136,19 +138,19 @@ HOSTDEVICE bool Grid::isQ(uint index) const
     return field[index] == Q;
 }
 
-HOSTDEVICE  bool Grid::isRb(uint index) const
+HOSTDEVICE bool Grid::isRb(uint index) const
 {
     return field[index] == VELOCITY || field[index] == PRESSURE || field[index] == NOSLIP || field[index] == SOLID;
 }
 
 HOSTDEVICE void Grid::setFieldEntryToFluid(uint index)
 {
-	this->field[index] = FLUID;
+    this->field[index] = FLUID;
 }
 
 HOSTDEVICE void Grid::setFieldEntryToSolid(uint index)
 {
-	this->field[index] = SOLID;
+    this->field[index] = SOLID;
 }
 
 HOST void Grid::setFieldEntryToInvalid(uint index)
@@ -168,29 +170,34 @@ HOSTDEVICE char Grid::getFieldEntry(const Vertex &v) const
 
 HOSTDEVICE int Grid::transCoordToIndex(const real &x, const real &y, const real &z) const
 {
-	return transCoordToIndex(Vertex(x,y,z));
+    return transCoordToIndex(Vertex(x,y,z));
 }
 
 HOSTDEVICE int Grid::transCoordToIndex(const Vertex &v) const
 {
+    const int x = int((v.x - startX) / delta);
+    const int y = int((v.y - startY) / delta);
+    const int z = int((v.z - startZ) / delta);
+
 #ifdef DEBUG
-	if (isOutOfRange(v))
-	{ printf("Function: transCoordToIndex. Coordinates are out of range and cannot calculate the index. Exit Program!\n");/* exit(1);*/ };
+    if (x < 0 || y < 0 || z < 0 || x >= nx || y >= ny || z >= nz)
+    {
+        printf(
+            "Function: transCoordToIndex. Coordinates are out of range and cannot calculate the index. Exit Program!\n");
+        /* exit(1);*/
+    }
 #endif
-    int x = (int)((v.x - startX) / delta);
-    int y = (int)((v.y - startY) / delta);
-    int z = (int)((v.z - startZ) / delta);
 
-	return x + nx * (y + ny * z);
+    return x + nx * (y + ny * z);
 }
 
 HOSTDEVICE void Grid::transIndexToCoords(const int index, real &x, real &y, real &z) const
 {
 #ifdef DEBUG
-	if (index < 0 || index >= (int)size)
-	{
+    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;
@@ -201,16 +208,10 @@ HOSTDEVICE void Grid::transIndexToCoords(const int index, real &x, real &y, real
     z = (z * delta) + startZ;
 }
 
-char* Grid::toString(const char* name) const
-{
-    std::stringstream ss;
-    ss << "\n" << name << " " << nx << " " << ny << " " << nz;
-    return strdup(ss.str().c_str());
-}
-
 HOSTDEVICE void Grid::print() const
 {
-    printf("min: (%2.2f, (%2.2f, %2.2f), max: (%2.2f, %2.2f, %2.2f), size: %d, delta: %2.2f\n", startX, startY, startZ, endX, endY, endZ, size, delta);
+    printf("min: (%2.2f, (%2.2f, %2.2f), max: (%2.2f, %2.2f, %2.2f), size: %d, delta: %2.2f\n", startX, startY, startZ,
+           endX, endY, endZ, size, delta);
 }
 
 HOSTDEVICE void Grid::setDebugPoint(const Vertex &point, const int pointValue)
@@ -218,22 +219,26 @@ HOSTDEVICE void Grid::setDebugPoint(const Vertex &point, const int pointValue)
     if (getFieldEntry(point) == INVALID_NODE && pointValue == SOLID)
         setFieldEntry(point, pointValue);
 
-	if (getFieldEntry(point) != SOLID && getFieldEntry(point) != Q && getFieldEntry(point) != INVALID_NODE && pointValue != 3 && pointValue != 2)
-		setFieldEntry(point, pointValue);
+    if (getFieldEntry(point) != SOLID && getFieldEntry(point) != Q && getFieldEntry(point) != INVALID_NODE && pointValue
+        != 3 && pointValue != 2)
+        setFieldEntry(point, pointValue);
 }
 
 HOSTDEVICE bool Grid::isOutOfRange(const Vertex &v) const
 {
-	return v.x < startX || v.y < startY || v.z < startZ || v.x > endX || v.y > endY || v.z > endZ;
+    return v.x < startX || v.y < startY || v.z < startZ || v.x > endX || v.y > endY || v.z > endZ;
 }
 
-HOSTDEVICE void Grid::meshTriangleExact(const Triangle &triangle)
+HOSTDEVICE void Grid::meshTriangle(const Triangle &triangle)
 {
     BoundingBox<real> box = BoundingBox<real>::makeRealNodeBox(triangle, delta);
 
-    for (real x = box.minX; x <= box.maxX; x += delta) {
-        for (real y = box.minY; y <= box.maxY; y += delta) {
-            for (real z = box.minZ; z <= box.maxZ; z += delta) {
+    for (real x = box.minX; x <= box.maxX; x += delta)
+    {
+        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;
@@ -247,50 +252,30 @@ HOSTDEVICE void Grid::meshTriangleExact(const Triangle &triangle)
     }
 }
 
-HOSTDEVICE void Grid::meshTriangle(const Triangle &triangle)
-{
-	int x, y, z;
-	Vertex point;
-
-	BoundingBox<int> box = BoundingBox<int>::makeNodeBox(triangle);
-
-	for (x = box.minX; x <= box.maxX; x++) {
-		for (y = box.minY; y <= box.maxY; y++) {
-			for (z = box.minZ; z <= box.maxZ; z++) {
-				point = Vertex((real)x, (real)y, (real)z);
-				if (isOutOfRange(point))
-					continue;
-                int value = triangle.isUnderFace(point);
-                setDebugPoint(point, value);
-
-                if (value == Q)
-                    calculateQs(point, triangle);
-			}
-		}
-	}
-}
-
 HOSTDEVICE void Grid::calculateQs(const Vertex &point, const Triangle &triangle)
 {
-	Vertex pointOnTriangle, direction;
-	//VertexInteger solid_node;
-	real subdistance;
-	int error;
-	for (int i = d.dir_start; i <= d.dir_end; i++) {
-	#if defined(__CUDA_ARCH__)
+    Vertex pointOnTriangle, direction;
+    //VertexInteger solid_node;
+    real subdistance;
+    int error;
+    for (int i = distribution.dir_start; i <= distribution.dir_end; i++)
+    {
+#if defined(__CUDA_ARCH__)
         direction = Vertex(DIRECTIONS[i][0], DIRECTIONS[i][1], DIRECTIONS[i][2]);
-	#else
-        direction = Vertex((real)d.dirs[i * DIMENSION + 0], (real)d.dirs[i * DIMENSION + 1], (real)d.dirs[i * DIMENSION + 2]);
-	#endif
+#else
+        direction = Vertex(real(distribution.dirs[i * DIMENSION + 0]), real(distribution.dirs[i * DIMENSION + 1]),
+                           real(distribution.dirs[i * DIMENSION + 2]));
+#endif
 
         error = triangle.getTriangleIntersection(point, direction, pointOnTriangle, subdistance);
 
-		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]);
-		}
-	}
+        if (error != 0 && subdistance <= 1.0f)
+        {
+            //solid_node = VertexInteger(actualPoint.x + direction.x, actualPoint.y + direction.y, actualPoint.z + direction.z);
+            distribution.f[i*size + transCoordToIndex(point)] = subdistance;
+            //printf("Q%d %d: %2.8f \n", i, grid.transCoordToIndex(actualPoint), grid.d.f[index]);
+        }
+    }
 }
 
 HOSTDEVICE void Grid::setNeighborIndices(const int &index)
@@ -301,15 +286,15 @@ HOSTDEVICE void Grid::setNeighborIndices(const int &index)
     real neighborX, neighborY, neighborZ;
     this->getNeighborCoords(neighborX, neighborY, neighborZ, x, y, z);
 
-	neighborIndexX[index] = (uint) transCoordToIndex(neighborX, y, z);
-    neighborIndexY[index] = (uint) transCoordToIndex(x, neighborY, z);
-    neighborIndexZ[index] = (uint) transCoordToIndex(x, y, neighborZ);
+    neighborIndexX[index] = uint(transCoordToIndex(neighborX, y, z));
+    neighborIndexY[index] = uint(transCoordToIndex(x, neighborY, z));
+    neighborIndexZ[index] = uint(transCoordToIndex(x, y, neighborZ));
 
-	//if (grid.isRB(index)) {
+    //if (grid.isRB(index)) {
     //if (neighborX == 0) neighborIndexX[index] = 0;
     //if (neighborY == 0) neighborIndexY[index] = 0;
     //if (neighborZ == 0) neighborIndexZ[index] = 0;
-	//}
+    //}
 }
 
 HOSTDEVICE void Grid::setInvalidNode(const int &index, bool &invalidNodeFound)
@@ -324,10 +309,10 @@ HOSTDEVICE void Grid::setInvalidNode(const int &index, bool &invalidNodeFound)
     }
 }
 
-
 HOSTDEVICE bool Grid::isNeighborInvalid(const int &index)
 {
-    return (field[neighborIndexX[index]] == INVALID_NODE || field[neighborIndexY[index]] == INVALID_NODE || field[neighborIndexZ[index]] == INVALID_NODE);
+    return (field[neighborIndexX[index]] == INVALID_NODE || field[neighborIndexY[index]] == INVALID_NODE || field[
+        neighborIndexZ[index]] == INVALID_NODE);
 }
 
 HOSTDEVICE void Grid::findNeighborIndex(int index)
@@ -340,10 +325,7 @@ HOSTDEVICE void Grid::findNeighborIndex(int index)
         return;
     }
 
-    real x, y, z;
-    this->transIndexToCoords(index, x, y, z);
-
-    if(this->isOverlapStopper(index))
+    if(this->isOverlapStopper(index) || isEndOfGridStopper(index))
     {
         this->setFieldEntryToSolid(index);
         this->neighborIndexX[index] = -1;
@@ -352,11 +334,13 @@ HOSTDEVICE void Grid::findNeighborIndex(int index)
         return;
     }
 
+    real x, y, z;
+    this->transIndexToCoords(index, x, y, z);
     real neighborXCoord, neighborYCoord, neighborZCoord;
     getNeighborCoords(neighborXCoord, neighborYCoord, neighborZCoord, x, y, z);
-    this->neighborIndexX[index] = getNeighborIndex(/*index, this->neighborIndexX[nodeIndex],*/ neighborXCoord, y, z);
-    this->neighborIndexY[index] = getNeighborIndex(/*index, this->neighborIndexY[nodeIndex],*/ x, neighborYCoord, z);
-    this->neighborIndexZ[index] = getNeighborIndex(/*index, this->neighborIndexZ[nodeIndex],*/ x, y, neighborZCoord);
+    this->neighborIndexX[index] = getNeighborIndex(neighborXCoord, y, z);
+    this->neighborIndexY[index] = getNeighborIndex(x, neighborYCoord, z);
+    this->neighborIndexZ[index] = getNeighborIndex(x, y, neighborZCoord);
 }
 
 HOSTDEVICE bool Grid::isOverlapStopper(uint index) const
@@ -391,34 +375,35 @@ HOSTDEVICE bool Grid::nodeInNextCellIsInvalid(int index) const
     const bool isInvalidNeighborXZ  = this->isInvalid(indexXZ);
     const bool isInvalidNeighborXYZ = this->isInvalid(indexXYZ);
 
-    return isInvalidNeighborX || isInvalidNeighborY || isInvalidNeighborXY || isInvalidNeighborZ || isInvalidNeighborYZ || isInvalidNeighborXZ || isInvalidNeighborXYZ;
+    return isInvalidNeighborX || isInvalidNeighborY || isInvalidNeighborXY || isInvalidNeighborZ || isInvalidNeighborYZ
+        || isInvalidNeighborXZ || isInvalidNeighborXYZ;
 }
 
-HOSTDEVICE int Grid::getNeighborIndex(/*const int &nodeIndex, const int &neighborIndex, */const real &expectedX, const real &expectedY, const real &expectedZ)
+HOSTDEVICE int Grid::getNeighborIndex(const real &expectedX, const real &expectedY, const real &expectedZ) const
 {
-
-    int neighborIndex = transCoordToIndex(expectedX, expectedY, expectedZ);
+    const int neighborIndex = transCoordToIndex(expectedX, expectedY, expectedZ);
     return matrixIndex[neighborIndex];
+}
 
-    //int newNeighborIndex = neighborIndex;
-    //while (newNeighborIndex >= (int)this->reducedSize)
-    //    newNeighborIndex--;
-
-    //if (newNeighborIndex >= 0)
-    //{
-    //    real neighborX, neighborY, neighborZ;
-    //    this->transIndexToCoords(this->matrixIndex[newNeighborIndex], neighborX, neighborY, neighborZ);
-    //    while (!(neighborX == expectedX && neighborY == expectedY && neighborZ == expectedZ)) {
-    //        newNeighborIndex--;
-    //        //printf("expectedNeighborCoords:(%d, %d, %d), actualNeighborCoords:(%d,%d,%d), neighborIndex: %d\n", expectedX, expectedY, expectedZ,neighborX ,neighborY ,neighborZ, neighborIndex);
-    //        this->transIndexToCoords(this->matrixIndex[newNeighborIndex], neighborX, neighborY, neighborZ);
-
-    //        if (newNeighborIndex == nodeIndex)
-    //            return -1;
-    //    }
-    //    return newNeighborIndex;
-    //}
-    //return -1;
+//void findForGridInterfaceNewIndex(GridInterface::Interface interface, uint interfaceIndex, int* indices)
+//{
+//    const uint oldIndex = interface.coarse[interfaceIndex];
+//    const uint newIndex = indices[oldIndex];
+//    interface.coarse[interfaceIndex] = newIndex;
+//}
+
+HOST void Grid::findForGridInterfaceNewIndexCF(uint index)
+{
+    const uint oldIndex = gridInterface->cf.coarse[index];
+    const uint newIndex = matrixIndex[oldIndex];
+    gridInterface->cf.coarse[index] = newIndex;
+}
+
+HOST void Grid::findForGridInterfaceNewIndexFC(uint index)
+{
+    const uint oldIndex = gridInterface->fc.coarse[index];
+    const uint newIndex = matrixIndex[oldIndex];
+    gridInterface->fc.coarse[index] = newIndex;
 }
 
 
@@ -439,62 +424,94 @@ HOST void Grid::removeInvalidNodes()
         }
     }
     reducedSize = size - removedNodes;
-    printf("new size coords: %zd , delete nodes: %zd\n", reducedSize, removedNodes);
+    printf("new size coords: %d , delete nodes: %d\n", reducedSize, removedNodes);
+}
 
+HOSTDEVICE void Grid::getNeighborCoords(real &neighborX, real &neighborY, real &neighborZ, const real x, const real y,
+                                       const real z) const
+{
+    neighborX = CudaMath::lessEqual(x + delta, endX) ? x + delta : startX;
+    neighborY = CudaMath::lessEqual(y + delta, endY) ? y + delta : startY;
+    neighborZ = CudaMath::lessEqual(z + delta, endZ) ? z + delta : startZ;
+}
 
-    //std::vector<uint> stl_vector(size);
-    //stl_vector.assign(this->matrixIndex, this->matrixIndex + this->size);
 
-    //int oldsize = (int)stl_vector.size();
-    //printf("size coords: %d \n", oldsize);
-    //std::vector<uint>::iterator end_vaild = std::remove_if(stl_vector.begin(), stl_vector.end(), [this](const uint &index)
-    //{
-    //    return this->field[index] == INVALID_NODE;
-    //});
 
-    //stl_vector.erase(end_vaild, stl_vector.end());
-    //printf("new size coords: %zd , delete nodes: %zd\n", stl_vector.size(), oldsize - stl_vector.size());
+HOST bool Grid::isEndOfGridStopper(uint index) const
+{
+    real x, y, z;
+    this->transIndexToCoords(index, x, y, z);
+    return (x > this->endX || y > this->endY || z > this->endZ);
+}
+
+
+//HOSTDEVICE  bool Grid::isStopper(int index) const
+//{
+//    return isSolid(index) && previousCellHasFluid(index);
+//}
+//
+//HOSTDEVICE  bool Grid::previousCellHasFluid(int index) const
+//{
+//    real x, y, z;
+//    this->transIndexToCoords(index, x, y, z);
+//
+//    real previousX = x - delta >= 0 ? x - delta : this->endX;
+//    real previousY = y - delta >= 0 ? y - delta : this->endY;
+//    real previousZ = z - delta >= 0 ? z - delta : this->endZ;
+//
+//    int indexpreviousX   = this->transCoordToIndex(previousX, y, z);
+//    int indexpreviousY   = this->transCoordToIndex(x, previousY, z);
+//    int indexpreviousXY  = this->transCoordToIndex(previousX, previousY, z);
+//    int indexpreviousZ   = this->transCoordToIndex(x, y, previousZ);
+//    int indexpreviousZX  = this->transCoordToIndex(previousX, y, previousZ);
+//    int indexpreviousZY  = this->transCoordToIndex(x, previousY, previousZ);
+//    int indexpreviousZYX = this->transCoordToIndex(previousX, previousY, previousZ);
+//
+//    return (!this->isSolid(indexpreviousX) || !this->isSolid(indexpreviousY) || !this->isSolid(indexpreviousZ)
+//        || !this->isSolid(indexpreviousZYX) || !this->isSolid(indexpreviousXY) || !this->isSolid(indexpreviousZY) || !
+//        this->isSolid(indexpreviousZX));
+//}
 
-    //uint *indices_reduced = new uint[stl_vector.size()];
-    //for (size_t i = 0; i < stl_vector.size(); i++)
-    //    indices_reduced[i] = stl_vector[i];
-    //
-    //this->reducedSize = (int)stl_vector.size();
-    //delete[]this->matrixIndex;
-    //this->matrixIndex = indices_reduced;
+
+uint Grid::getNumberOfNodes() const
+{
+    return this->reducedSize;
 }
 
-HOSTDEVICE void Grid::getNeighborCoords(real &neighborX, real &neighborY, real &neighborZ, const real x, const real y, const real z) const
+uint Grid::getNumberOfNodesCF() const
 {
-	neighborX = x + delta < endX ? x + delta : startX;
-    neighborY = y + delta < endY ? y + delta : startY;
-    neighborZ = z + delta < endZ ? z + delta : startZ;
+    return this->gridInterface->cf.numberOfEntries;
 }
 
-HOSTDEVICE bool Grid::isStopper(int index) const
+uint Grid::getNumberOfNodesFC() const
 {
-    return isSolid(index) && previousCellHasFluid(index);
+    return this->gridInterface->fc.numberOfEntries;
 }
 
+void Grid::setCFC(uint* iCellCfc) const
+{
+    setGridInterface(iCellCfc, this->gridInterface->cf.coarse, this->gridInterface->cf.numberOfEntries);
+}
 
+void Grid::setCFF(uint* iCellCff) const
+{
+    setGridInterface(iCellCff, this->gridInterface->cf.fine, this->gridInterface->cf.numberOfEntries);
+}
 
-HOSTDEVICE bool Grid::previousCellHasFluid(int index) const
+void Grid::setFCC(uint* iCellFcc) const
 {
-    real x, y, z;
-    this->transIndexToCoords(index, x, y, z);
+    setGridInterface(iCellFcc, this->gridInterface->fc.coarse, this->gridInterface->fc.numberOfEntries);
+}
 
-    real previousX = x - delta >= 0 ? x - delta : this->endX;
-    real previousY = y - delta >= 0 ? y - delta : this->endY;
-    real previousZ = z - delta >= 0 ? z - delta : this->endZ;
+void Grid::setFCF(uint* iCellFcf) const
+{
+    setGridInterface(iCellFcf, this->gridInterface->fc.fine, this->gridInterface->fc.numberOfEntries);
+}
 
-    int indexpreviousX   = this->transCoordToIndex(previousX, y, z);
-    int indexpreviousY   = this->transCoordToIndex(x, previousY, z);
-    int indexpreviousXY  = this->transCoordToIndex(previousX, previousY, z);
-    int indexpreviousZ   = this->transCoordToIndex(x, y, previousZ);
-    int indexpreviousZX  = this->transCoordToIndex(previousX, y, previousZ);
-    int indexpreviousZY  = this->transCoordToIndex(x, previousY, previousZ);
-    int indexpreviousZYX = this->transCoordToIndex(previousX, previousY, previousZ);
 
-    return (!this->isSolid(indexpreviousX) || !this->isSolid(indexpreviousY) || !this->isSolid(indexpreviousZ)
-        || !this->isSolid(indexpreviousZYX) || !this->isSolid(indexpreviousXY) || !this->isSolid(indexpreviousZY) || !this->isSolid(indexpreviousZX));
+void Grid::setGridInterface(uint* gridInterfaceList, const uint* oldGridInterfaceList, uint size)
+{
+    for (uint i = 0; i < size; i++)
+        gridInterfaceList[i] = oldGridInterfaceList[i] + 1;
 }
+
diff --git a/src/GridGenerator/grid/Grid.cuh b/src/GridGenerator/grid/Grid.cuh
index a0979964ce398697c0a1a8b3fa1569a822adb5e3..17825cb3386adba8e58d090126f6e498261529f6 100644
--- a/src/GridGenerator/grid/Grid.cuh
+++ b/src/GridGenerator/grid/Grid.cuh
@@ -2,9 +2,9 @@
 #define GRID_H
 
 #include "GridGenerator/global.h"
+#include "distributions/Distribution.h"
 
-
-#include <GridGenerator/grid/distributions/Distribution.h>
+#define DIR_END_MAX 27
 
 struct Geometry;
 struct Vertex;
@@ -16,6 +16,14 @@ extern CONSTANT int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
 struct VF_PUBLIC Grid : enableSharedFromThis<Grid>
 {
+private:
+    HOST Grid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, SPtr<GridStrategy> gridStrategy, Distribution d);
+    HOST Grid();
+
+public:
+    HOST ~Grid();
+    static HOST SPtr<Grid> makeShared(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, std::shared_ptr<GridStrategy> gridStrategy, Distribution d);
+
     real startX = 0.0, startY = 0.0, startZ = 0.0;
     real endX, endY, endZ;
     real delta = 1.0;
@@ -23,20 +31,13 @@ struct VF_PUBLIC Grid : enableSharedFromThis<Grid>
 	char *field;
 	uint nx, ny, nz;
 	uint size;
-	Distribution d;
-
-    GridInterface* gridInterface;
 
     int *neighborIndexX, *neighborIndexY, *neighborIndexZ;
 
     int *matrixIndex;
     uint reducedSize;
+    Distribution distribution;
 
-    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> makeShared(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();
@@ -64,32 +65,50 @@ struct VF_PUBLIC Grid : enableSharedFromThis<Grid>
 	HOSTDEVICE bool isOutOfRange(const Vertex &actualPoint) const;
 
 	/*---------------------------------------------------------------------------------*/
-	HOSTDEVICE void meshTriangle(const Triangle &actualTriangle);
-    HOSTDEVICE void meshTriangleExact(const Triangle &triangle);
-
+    HOSTDEVICE void meshTriangle(const Triangle &triangle);
 	HOSTDEVICE void calculateQs(const Vertex &point, const Triangle &actualTriangle);
-
-	char* toString(const char* name) const;
-
     /*---------------------------------------------------------------------------------*/
     HOSTDEVICE void setNeighborIndices(const int &index);
 	HOSTDEVICE void getNeighborCoords(real &neighborX, real &neighborY, real &neighborZ, const real x, const real y, const real z) const;
     HOSTDEVICE void findNeighborIndex(int index);
-    HOSTDEVICE int getNeighborIndex(/*const int &nodeIndex, const int &neighborIndex, */const real &expectedX, const real &expectedY, const real &expectedZ);
+    HOST void findForGridInterfaceNewIndexCF(uint index);
+    HOST void findForGridInterfaceNewIndexFC(uint index);
+
+    HOSTDEVICE int getNeighborIndex(/*const int &nodeIndex, const int &neighborIndex, */const real &expectedX, const real &expectedY, const real &expectedZ) const;
 
     HOSTDEVICE void setInvalidNode(const int &index, bool &invalidNodeFound);
     HOSTDEVICE bool isNeighborInvalid(const int &index);
 
     HOST void removeInvalidNodes();
 
-    HOSTDEVICE bool isStopper(int index) const;
+    //HOSTDEVICE bool isStopper(int index) const;
+    HOST bool isEndOfGridStopper(uint index) const;
+
+
+    HOST uint getNumberOfNodes() const;
+
+    HOST uint getNumberOfNodesCF() const;
+    HOST uint getNumberOfNodesFC() const;
+
+    HOST void setCFC(uint* iCellCfc) const;
+    HOST void setCFF(uint* iCellCff) const;
+    HOST void setFCC(uint* iCellFcc) const;
+    HOST void setFCF(uint* iCellFcf) const;
+
+private:
+    static void setGridInterface(uint* gridInterfaceList, const uint* oldGridInterfaceList, uint size);
+
 private:
-    HOSTDEVICE bool previousCellHasFluid(int index) const;
+    //HOSTDEVICE bool previousCellHasFluid(int index) const;
 
     HOSTDEVICE bool nodeInNextCellIsInvalid(int index) const;
 
     SPtr<GridStrategy> gridStrategy;
 
+    GridInterface* gridInterface;
+
+    friend class GridGpuStrategy;
+    friend class GridCpuStrategy;
 
 };
 
diff --git a/src/GridGenerator/grid/GridBuilder/GridBuilder.h b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
index 34abe95dc94e63ea6f43a3f1401ea951c7347ca4..8a8cfab474cc5823b0f1f3c6265ab17999b3662d 100644
--- a/src/GridGenerator/grid/GridBuilder/GridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
@@ -40,13 +40,11 @@ public:
 
     virtual VF_PUBLIC ~GridBuilder() {}
     virtual void getGridInformations(std::vector<int>& gridX, std::vector<int>& gridY, std::vector<int>& gridZ, std::vector<int>& distX, std::vector<int>& distY, std::vector<int>& distZ) = 0;
-    virtual int getNumberOfGridLevels() = 0;
+    virtual VF_PUBLIC uint getNumberOfGridLevels() = 0;
 
     virtual void meshGeometry(std::string input, int level) = 0;
     virtual void deleteSolidNodes() = 0;
 
-	virtual void flood(Vertex &startFlood, int level) = 0;
-
 	virtual void writeGridToVTK(std::string output, int level) = 0;
     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;
@@ -70,6 +68,8 @@ public:
     virtual void setCFF(uint* iCellCff, int level) = 0;
     virtual void setFCC(uint* iCellFcc, int level) = 0;
     virtual void setFCF(uint* iCellFcf, int level) = 0;
+    virtual void setOffsetFC(real* xOffCf, real* yOffCf, real* zOffCf, int level) = 0;
+    virtual void setOffsetCF(real* xOffFc, real* yOffFc, real* zOffFc, int level) = 0;
 };
 
 #endif
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
index 37a114c3e6ee06f11bc35fa22dcc5303eb4ab335..f2da132a1c5ee509fdd8d791d6a3f526d0e9aafb 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
@@ -79,85 +79,92 @@ void LevelGridBuilder::getGridInformations(std::vector<int>& gridX, std::vector<
     }
 }
 
-int LevelGridBuilder::getNumberOfGridLevels()
+void LevelGridBuilder::removeOverlapNodes()
+{
+    for (int level = 0; level < grids.size() - 1; level++)
+        grids[level]->removeOverlapNodes(grids[level + 1]);
+}
+
+
+void LevelGridBuilder::meshGeometry(std::string input, int level)
+{
+    checkLevel(level);
+
+    Geometry geometry(input);
+
+    if (geometry.size > 0)
+        this->grids[level]->mesh(geometry);
+
+}
+
+
+uint LevelGridBuilder::getNumberOfGridLevels()
 {
     return grids.size();
 }
 
 uint LevelGridBuilder::getNumberOfNodesCF(int level)
 {
-    return this->grids[level]->gridInterface->cf.numberOfEntries;
+    return this->grids[level]->getNumberOfNodesCF();
 }
 
 uint LevelGridBuilder::getNumberOfNodesFC(int level)
 {
-    return this->grids[level]->gridInterface->fc.numberOfEntries;
+    return this->grids[level]->getNumberOfNodesFC();
 }
 
 void LevelGridBuilder::setCFC(uint* iCellCfc, int level)
 {
-    for (int i = 0; i < this->grids[level]->gridInterface->cf.numberOfEntries; i++)
-        iCellCfc[i] = this->grids[level]->gridInterface->cf.coarse[i];
+    this->grids[level]->setCFC(iCellCfc);
 }
 
 void LevelGridBuilder::setCFF(uint* iCellCff, int level)
 {
-    for (int i = 0; i < this->grids[level]->gridInterface->cf.numberOfEntries; i++)
-        iCellCff[i] = this->grids[level]->gridInterface->cf.fine[i];
+    this->grids[level]->setCFF(iCellCff);
 }
 
 void LevelGridBuilder::setFCC(uint* iCellFcc, int level)
 {
-    for (int i = 0; i < this->grids[level]->gridInterface->fc.numberOfEntries; i++)
-        iCellFcc[i] = this->grids[level]->gridInterface->fc.coarse[i];
+    this->grids[level]->setFCC(iCellFcc);
 }
 
 void LevelGridBuilder::setFCF(uint* iCellFcf, int level)
 {
-    for (int i = 0; i < this->grids[level]->gridInterface->fc.numberOfEntries; i++)
-        iCellFcf[i] = this->grids[level]->gridInterface->fc.fine[i];
+    this->grids[level]->setFCF(iCellFcf);
 }
 
-
-void LevelGridBuilder::removeOverlapNodes()
+void LevelGridBuilder::setOffsetFC(real * xOffCf, real * yOffCf, real * zOffCf, int level)
 {
-    for (int level = 0; level < grids.size() - 1; level++)
-        grids[level]->removeOverlapNodes(grids[level + 1]);
+    for (uint i = 0; i < getNumberOfNodesFC(level); i++)
+    {
+        xOffCf[i] = 0.0;
+        yOffCf[i] = 0.0;
+        zOffCf[i] = 0.0;
+    }
 }
 
-
-void LevelGridBuilder::meshGeometry(std::string input, int level)
+void LevelGridBuilder::setOffsetCF(real * xOffFc, real * yOffFc, real * zOffFc, int level)
 {
-    checkLevel(level);
-
-    Geometry geometry(input);
-
-    if (geometry.size > 0)
-        this->grids[level]->mesh(geometry);
-
+    for (uint i = 0; i < getNumberOfNodesCF(level); i++)
+    {
+        xOffFc[i] = 0.0;
+        yOffFc[i] = 0.0;
+        zOffFc[i] = 0.0;
+    }
 }
 
+
 void LevelGridBuilder::deleteSolidNodes()
 {
     //this->gridWrapper[0]->deleteSolidNodes();
     //this->gridWrapper[0]->copyDataFromGPU();
 }
 
-void LevelGridBuilder::flood(Vertex &startFlood, int level)
-{
-    checkLevel(level);
-    //this->gridWrapper[level]->floodFill(startFlood);
-}
-
-void LevelGridBuilder::createBoundaryConditions()
-{
-    this->createBCVectors();
-}
 
 
-unsigned int LevelGridBuilder::getNumberOfNodes(unsigned int level) const
+uint LevelGridBuilder::getNumberOfNodes(unsigned int level) const
 {
-    return (unsigned int) grids[level]->reducedSize;
+    return grids[level]->getNumberOfNodes();
 }
 
 std::vector<std::vector<std::vector<real> > > LevelGridBuilder::getQsValues() const
@@ -179,8 +186,7 @@ void LevelGridBuilder::writeGridToVTK(std::string output, int level)
 {
    checkLevel(level);
    GridVTKWriter::writeGridToVTKXML(*grids[level].get(), output);
-
-
+   GridVTKWriter::writeSparseGridToVTK(*grids[level].get(), output);
 }
 
 
@@ -282,6 +288,10 @@ void LevelGridBuilder::setPressValues(real* RhoBC, int* kN, int channelSide, int
 }
 
 
+void LevelGridBuilder::createBoundaryConditions()
+{
+    this->createBCVectors();
+}
 
 /*#################################################################################*/
 /*---------------------------------private methods---------------------------------*/
@@ -313,10 +323,10 @@ void LevelGridBuilder::addShortQsToVector(int index)
 
     Grid grid = *grids[0].get();
 
-    for (int i = grid.d.dir_end; i >= 0; i--)
+    for (int i = grid.distribution.dir_end; i >= 0; i--)
     {
         int qIndex = i * grid.size + grid.matrixIndex[index];
-        real q = grid.d.f[qIndex];
+        real q = grid.distribution.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);
@@ -339,10 +349,10 @@ void LevelGridBuilder::addQsToVector(int index)
 
     Grid grid = *grids[0].get();
 
-    for (int i = grid.d.dir_end; i >= 0; i--)
+    for (int i = grid.distribution.dir_end; i >= 0; i--)
     {
         int qIndex = i * grid.size + grid.matrixIndex[index];
-        real q = grid.d.f[qIndex];
+        real q = grid.distribution.f[qIndex];
         if (q > 0)
             qNode.push_back(q);
         else
@@ -359,9 +369,9 @@ void LevelGridBuilder::fillRBForNode(int x, int y, int z, int index, int directi
 
     Grid grid = *grids[0].get();
 
-    for (int i = grid.d.dir_end; i >= 0; i--)
+    for (int i = grid.distribution.dir_end; i >= 0; i--)
     {
-        if (grid.d.dirs[i * DIMENSION + direction] != directionSign)
+        if (grid.distribution.dirs[i * DIMENSION + direction] != directionSign)
             continue;
 
         qKey += (uint32_t)pow(2, 26 - i);
@@ -397,8 +407,8 @@ void LevelGridBuilder::writeArrow(const int i, const int qi, const Vertex& start
     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]);
+        int qReverse = grid.distribution.dir_end - qi;
+        Vertex dir((real)grid.distribution.dirs[qReverse * DIMENSION + 0], (real)grid.distribution.dirs[qReverse* DIMENSION + 1], (real)grid.distribution.dirs[qReverse * DIMENSION + 2]);
         Vertex nodeOnGeometry(startNode + (dir * qval));
         std::shared_ptr<Arrow> arrow = ArrowImp::make(startNode, nodeOnGeometry);
         trans->transformGridToWorld(arrow);
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
index 9e566944ad7218adcada5a9bf86105cc554f2e2e..a2651dd4f0c928cc5b89c9a35905109830b00308 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "GridBuilder.h"
+#include "grid/GridInterface.cuh"
 
 struct Vertex;
 struct Grid;
@@ -34,8 +35,6 @@ public:
     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);
 
@@ -85,13 +84,18 @@ public:
     VF_PUBLIC void getGridInformations(std::vector<int>& gridX, std::vector<int>& gridY,
         std::vector<int>& gridZ, std::vector<int>& distX, std::vector<int>& distY,
         std::vector<int>& distZ) override;
-    VF_PUBLIC int getNumberOfGridLevels() override;
+    VF_PUBLIC uint getNumberOfGridLevels() override;
+
     VF_PUBLIC uint getNumberOfNodesCF(int level) override;
     VF_PUBLIC uint getNumberOfNodesFC(int level) override;
+
     VF_PUBLIC void setCFC(uint* iCellCfc, int level) override;
     VF_PUBLIC void setCFF(uint* iCellCff, int level) override;
     VF_PUBLIC void setFCC(uint* iCellFcc, int level) override;
     VF_PUBLIC void setFCF(uint* iCellFcf, int level) override;
+
+    VF_PUBLIC void setOffsetFC(real* xOffCf, real* yOffCf, real* zOffCf, int level) override;
+    VF_PUBLIC void setOffsetCF(real* xOffFc, real* yOffFc, real* zOffFc, int level) override;
 };
 
 #endif
diff --git a/src/GridGenerator/grid/GridFactory.cpp b/src/GridGenerator/grid/GridFactory.cpp
index 89693c42bba67708ec630a6382c5b1eff1cf070b..0728f2bef6bcf162f337ef4555b434aaaeb0acab 100644
--- a/src/GridGenerator/grid/GridFactory.cpp
+++ b/src/GridGenerator/grid/GridFactory.cpp
@@ -2,6 +2,7 @@
 
 #include "grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h"
 #include "grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.h"
+#include "distributions/Distribution.h"
 
 
 SPtr<Grid> GridFactory::makeGrid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta,
diff --git a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
index 806fadc1556381232ee2a5cac9068e9804214da5..a525f51883f66fdfe3a9f269e2defe67558647ba 100644
--- a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
+++ b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.cpp
@@ -26,12 +26,12 @@ void GridCpuStrategy::allocateGridMemory(SPtr<Grid> grid)
     grid->matrixIndex = new int[grid->size];
 
 
-    unsigned long distributionSize = grid->size * (grid->d.dir_end + 1);
+    unsigned long distributionSize = grid->size * (grid->distribution.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
+    grid->distribution.f = new real[distributionSize](); // automatic initialized with zeros
 }
 
 void GridCpuStrategy::initalNodes(SPtr<Grid> grid)
@@ -39,9 +39,20 @@ void GridCpuStrategy::initalNodes(SPtr<Grid> grid)
 #pragma omp parallel for
     for (uint index = 0; index < grid->size; index++)
     {
-        grid->setNeighborIndices(index);
         grid->matrixIndex[index] = index;
-        grid->setFieldEntryToFluid(index);
+        if(grid->isEndOfGridStopper(index))
+        {
+            grid->setFieldEntryToSolid(index);
+            grid->neighborIndexX[index] = -1;
+            grid->neighborIndexY[index] = -1;
+            grid->neighborIndexZ[index] = -1;
+        } 
+        else
+        {
+            grid->setFieldEntryToFluid(index);
+            grid->setNeighborIndices(index);
+        }
+            
     }
 }
 
@@ -49,7 +60,7 @@ 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]);
+        grid->meshTriangle(geom.triangles[i]);
 }
 
 void GridCpuStrategy::removeOverlapNodes(SPtr<Grid> grid, SPtr<Grid> finerGrid)
@@ -58,7 +69,8 @@ void GridCpuStrategy::removeOverlapNodes(SPtr<Grid> grid, SPtr<Grid> finerGrid)
 
     setOverlapNodesToInvalid(grid, finerGrid);
     grid->removeInvalidNodes();
-    findNeighborIndices(grid);
+    findForNeighborsNewIndices(grid);
+    findForGridInterfaceNewIndices(grid);
 }
 
 void GridCpuStrategy::setOverlapNodesToInvalid(SPtr<Grid> grid, SPtr<Grid> finerGrid)
@@ -67,13 +79,24 @@ void GridCpuStrategy::setOverlapNodesToInvalid(SPtr<Grid> grid, SPtr<Grid> finer
         grid->setOverlapNodeToInvalid(index, *finerGrid.get());
 }
 
-void GridCpuStrategy::findNeighborIndices(SPtr<Grid> grid)
+void GridCpuStrategy::findForNeighborsNewIndices(SPtr<Grid> grid)
 {
 #pragma omp parallel for
     for (uint index = 0; index < grid->size; index++)
         grid->findNeighborIndex(index);
 }
 
+void GridCpuStrategy::findForGridInterfaceNewIndices(SPtr<Grid> grid)
+{
+#pragma omp parallel for
+    for (uint index = 0; index < grid->gridInterface->cf.numberOfEntries; index++)
+        grid->findForGridInterfaceNewIndexCF(index);
+
+#pragma omp parallel for
+    for (uint index = 0; index < grid->gridInterface->fc.numberOfEntries; index++)
+        grid->findForGridInterfaceNewIndexFC(index);
+}
+
 
 void GridCpuStrategy::deleteSolidNodes(SPtr<Grid> grid)
 {
@@ -81,7 +104,7 @@ void GridCpuStrategy::deleteSolidNodes(SPtr<Grid> grid)
 
     findInvalidNodes(grid);
     grid->removeInvalidNodes();
-    findNeighborIndices(grid);
+    findForNeighborsNewIndices(grid);
 
     clock_t end = clock();
     real time = (real)(real(end - begin) / CLOCKS_PER_SEC);
@@ -113,6 +136,6 @@ void GridCpuStrategy::freeMemory(SPtr<Grid> grid)
     delete[] grid->neighborIndexZ;
     delete[] grid->matrixIndex;
 
-    delete[] grid->d.f;
+    delete[] grid->distribution.f;
 }
 
diff --git a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
index 8b8c25c2e5f620d623e69a24487f74f89386e700..652d4c5b5bd1d79538ff7819ccb17e1dfae56561 100644
--- a/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
+++ b/src/GridGenerator/grid/GridStrategy/GridCpuStrategy/GridCpuStrategy.h
@@ -32,7 +32,9 @@ public:
 
 protected:
     static void findInvalidNodes(SPtr<Grid> grid);
-    static void findNeighborIndices(SPtr<Grid> grid);
+    static void findForNeighborsNewIndices(SPtr<Grid> grid);
+    static void findForGridInterfaceNewIndices(SPtr<Grid> grid);
+
     static void setOverlapNodesToInvalid(SPtr<Grid> grid, SPtr<Grid> finerGrid);
 
 };
diff --git a/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
index 9f51ea8833f2a6c44d9cc5f8c2cad147cedc692d..baf55b0b976692786b39c32d964f6bb0f1b0a619 100644
--- a/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
+++ b/src/GridGenerator/grid/GridStrategy/GridGpuStrategy/GridGpuStrategy.cpp
@@ -12,6 +12,7 @@
 #include <GridGenerator/grid/kernel/runGridKernelGPU.cuh>
 #include <GridGenerator/grid/Grid.cuh>
 
+#include <grid/distributions/Distribution.h>
 
 #include <utilities/logger/Logger.h>
 #include <helper_cuda.h>
@@ -94,7 +95,7 @@ void GridGpuStrategy::freeMemory(SPtr<Grid> grid)
     delete[] grid->neighborIndexZ;
     delete[] grid->matrixIndex;
 
-    delete[] grid->d.f;
+    delete[] grid->distribution.f;
 }
 
 
@@ -132,15 +133,15 @@ void GridGpuStrategy::allocField(SPtr<Grid> grid)
 
 void GridGpuStrategy::allocDistribution(SPtr<Grid> grid)
 {
-    CudaSafeCall(cudaMemcpyToSymbol(DIRECTIONS, grid->d.dirs, grid->d.dir_end * DIMENSION * sizeof(int)));
+    CudaSafeCall(cudaMemcpyToSymbol(DIRECTIONS, grid->distribution.dirs, grid->distribution.dir_end * DIMENSION * sizeof(int)));
     CudaCheckError();
 
-    unsigned long long distributionSize = grid->size * (grid->d.dir_end + 1);
+    unsigned long long distributionSize = grid->size * (grid->distribution.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));
+    checkCudaErrors(cudaMalloc(&grid->distribution.f, size_in_bytes));
     CudaCheckError();
 }
 
@@ -226,12 +227,12 @@ void GridGpuStrategy::copyAndFreeFieldFromGPU(SPtr<Grid> grid)
 
 void GridGpuStrategy::copyAndFreeDistributiondFromGPU(SPtr<Grid> grid)
 {
-    unsigned long long distributionSize = grid->size * (grid->d.dir_end + 1);
+    unsigned long long distributionSize = grid->size * (grid->distribution.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));
+    CudaSafeCall(cudaMemcpy(f_host, grid->distribution.f, distributionSize * sizeof(real), cudaMemcpyDeviceToHost));
+    CudaSafeCall(cudaFree(grid->distribution.f));
     CudaCheckError();
-    grid->d.f = f_host;
+    grid->distribution.f = f_host;
 }
 
 
diff --git a/src/GridGenerator/grid/GridTest.cpp b/src/GridGenerator/grid/GridTest.cpp
index d30d45f18c89f11151f2918198534dbaa0fddc37..4a19dd2a62479a5e0c144aed9ebfccfb3dbc7853 100644
--- a/src/GridGenerator/grid/GridTest.cpp
+++ b/src/GridGenerator/grid/GridTest.cpp
@@ -7,204 +7,204 @@
 #include <GridGenerator/geometries/BoundingBox/BoundingBox.cuh>
 #include "GridStrategy/GridCpuStrategy/GridCpuStrategy.h"
 
-
-std::vector<Vertex> getPointsInBoundingBox(Triangle t, real delta)
-{
-	int x, y, z;
-	BoundingBox<int> box = BoundingBox<int>::makeNodeBox(t);
-
-	std::vector<Vertex> points;
-
-	for (x = box.minX; x <= box.maxX; x++) {
-		for (y = box.minY; y <= box.maxY; y++) {
-			for (z = box.minZ; z <= box.maxZ; z++) {
-				points.push_back(Vertex((real)x, (real)y, (real)z));
-			}
-		}
-	}
-
-	return points;
-}
-
-
-TEST(GridTest, transIndexToCoordsAndCoordToIndex)
-{
-	Grid grid(nullptr, 0, 0, 0, 10, 10, 10, Distribution());
-
-	int index = 756;
-	real x, y, z;
-	grid.transIndexToCoords(index, x, y, z);
-
-	real expectedX = 6;
-	real expectedY = 5;
-	real expectedZ = 7;
-
-	EXPECT_THAT(x, expectedX);
-	EXPECT_THAT(y, expectedY);
-	EXPECT_THAT(z, expectedZ);
-
-	unsigned int newIndex = grid.transCoordToIndex(expectedX, expectedY, expectedZ);
-
-	EXPECT_THAT(newIndex, index);
-}
-
-
-TEST(GridTest, checkIfPointIsOutOfRange)
-{
-	Grid grid(nullptr, 5, 5, 5, 10, 10, 10, Distribution());
-	EXPECT_TRUE(grid.isOutOfRange(Vertex(0, 0, 0)));
-}
-
-TEST(GridTest, checkIfPointIsNotOutOfRange)
-{
-	Grid grid(nullptr, 5, 5, 5, 10, 10, 10, Distribution());
-	EXPECT_FALSE(grid.isOutOfRange(Vertex(8, 8, 5)));
-}
+//
+//std::vector<Vertex> getPointsInBoundingBox(Triangle t, real delta)
+//{
+//	int x, y, z;
+//	BoundingBox<int> box = BoundingBox<int>::makeNodeBox(t);
+//
+//	std::vector<Vertex> points;
+//
+//	for (x = box.minX; x <= box.maxX; x++) {
+//		for (y = box.minY; y <= box.maxY; y++) {
+//			for (z = box.minZ; z <= box.maxZ; z++) {
+//				points.push_back(Vertex((real)x, (real)y, (real)z));
+//			}
+//		}
+//	}
+//
+//	return points;
+//}
+//
+//
+//TEST(GridTest, transIndexToCoordsAndCoordToIndex)
+//{
+//	Grid grid(nullptr, 0, 0, 0, 10, 10, 10, Distribution());
+//
+//	int index = 756;
+//	real x, y, z;
+//	grid.transIndexToCoords(index, x, y, z);
+//
+//	real expectedX = 6;
+//	real expectedY = 5;
+//	real expectedZ = 7;
+//
+//	EXPECT_THAT(x, expectedX);
+//	EXPECT_THAT(y, expectedY);
+//	EXPECT_THAT(z, expectedZ);
+//
+//	unsigned int newIndex = grid.transCoordToIndex(expectedX, expectedY, expectedZ);
+//
+//	EXPECT_THAT(newIndex, index);
+//}
+//
+//
+//TEST(GridTest, checkIfPointIsOutOfRange)
+//{
+//	Grid grid(nullptr, 5, 5, 5, 10, 10, 10, Distribution());
+//	EXPECT_TRUE(grid.isOutOfRange(Vertex(0, 0, 0)));
+//}
+//
+//TEST(GridTest, checkIfPointIsNotOutOfRange)
+//{
+//	Grid grid(nullptr, 5, 5, 5, 10, 10, 10, Distribution());
+//	EXPECT_FALSE(grid.isOutOfRange(Vertex(8, 8, 5)));
+//}
 
 
 
 #include <GridGenerator/grid/distributions/Distribution.h>
 #include <GridGenerator/grid/NodeValues.h>
 
-
-class GridStopperTest : public testing::Test
-{
-public:
-    Grid grid;
-
-    void SetUp()
-    {
-        int nx = 2;
-        int ny = 2;
-        int nz = 2;
-        int size = nx*ny*nz;
-
-        char *field = new char[size]();
-        grid = Grid(field, 0, 0, 0, nx, ny, nz, DistributionHelper::getDistribution27());
-    }
-};
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfeveryNodeBeforeIsSolid_ItShouldNotBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_FALSE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = FLUID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusYisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = FLUID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusZisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = FLUID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXYZisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = FLUID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXYisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = FLUID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusYZisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = FLUID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
-
-TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXZisFluid_ItShouldBeAStopperNode)
-{
-    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
-
-    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
-    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
-    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
-    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
-    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
-    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
-    grid.field[grid.transCoordToIndex(0, 1, 0)] = FLUID; // -xz
-
-    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
-}
+//
+//class GridStopperTest : public testing::Test
+//{
+//public:
+//    Grid grid;
+//
+//    void SetUp()
+//    {
+//        int nx = 2;
+//        int ny = 2;
+//        int nz = 2;
+//        int size = nx*ny*nz;
+//
+//        char *field = new char[size]();
+//        grid = Grid(field, 0, 0, 0, nx, ny, nz, DistributionHelper::getDistribution27());
+//    }
+//};
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfeveryNodeBeforeIsSolid_ItShouldNotBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_FALSE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = FLUID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusYisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = FLUID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusZisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = FLUID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXYZisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = FLUID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXYisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = FLUID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusYZisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = FLUID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = SOLID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
+//
+//TEST_F(GridStopperTest, testIfNodeIsStopper_IfMinusXZisFluid_ItShouldBeAStopperNode)
+//{
+//    grid.field[grid.transCoordToIndex(1, 1, 1)] = SOLID; // node
+//
+//    grid.field[grid.transCoordToIndex(0, 1, 1)] = SOLID; // -x
+//    grid.field[grid.transCoordToIndex(1, 0, 1)] = SOLID; // -y
+//    grid.field[grid.transCoordToIndex(1, 1, 0)] = SOLID; // -z
+//    grid.field[grid.transCoordToIndex(0, 0, 0)] = SOLID; // -xyz
+//    grid.field[grid.transCoordToIndex(0, 0, 1)] = SOLID; // -xy
+//    grid.field[grid.transCoordToIndex(1, 0, 0)] = SOLID; // -yz
+//    grid.field[grid.transCoordToIndex(0, 1, 0)] = FLUID; // -xz
+//
+//    ASSERT_TRUE(grid.isStopper(grid.transCoordToIndex(1, 1, 1)));
+//}
 
 TEST(GridTest, transRealCoordsToIndex)
 {
diff --git a/src/GridGenerator/grid/kernel/runGridKernelGPU.cu b/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
index 73f204a28f7147609a8363ec6b67d9094a3645b1..ceaad78b026cef114f37e9f676afdc327d5c7f41 100644
--- a/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
+++ b/src/GridGenerator/grid/kernel/runGridKernelGPU.cu
@@ -43,7 +43,7 @@ GLOBAL void runMeshing(Grid grid, const Geometry geom)
 {
 	unsigned int i = LaunchParameter::getGlobalIdx_1D_1D();
 	if (i < geom.size)
-		grid.meshTriangleExact(geom.triangles[i]);
+		grid.meshTriangle(geom.triangles[i]);
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/src/GridGenerator/utilities/cuda/cudaDefines.h b/src/GridGenerator/utilities/cuda/cudaDefines.h
index 10e6b81aa4ca13ca37576f16fa0071f2c5d75c0e..2bb7a070d20cedf085335f13bc2064eea69154b6 100644
--- a/src/GridGenerator/utilities/cuda/cudaDefines.h
+++ b/src/GridGenerator/utilities/cuda/cudaDefines.h
@@ -10,7 +10,7 @@
 #define CONSTANT __constant__
 
 
-#define HOSTDEVICE HOST DEVICE
+#define HOSTDEVICE HOST DEVICE 
 
 static void printCudaInformation(int i) {
     cudaDeviceProp prop;
diff --git a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
index 9cfa9914f8edddf566e39827b4a2df8f7e45fad9..7d0db1e1b1d6aab0b1b4ba114d443a97b07bc99d 100644
--- a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
+++ b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
@@ -18,11 +18,6 @@ GridGenerator::~GridGenerator()
 
 }
 
-void GridGenerator::setUnstructuredGridBuilder(std::shared_ptr<GridBuilder> builder)
-{
-	this->builder = builder;
-}
-
 void GridGenerator::initalGridInformations()
 {
     std::vector<int> gridX, gridY, gridZ;
@@ -200,27 +195,22 @@ void GridGenerator::allocArrays_OffsetScale()
 {
     int maxLevel = para->getMaxLevel();
 
-    int numberOfNodesCF = 0;
-    int numberOfNodesFC = 0;
-
-    for (int level = 0; level < maxLevel; level++) {
+    for (int level = 0; level < maxLevel; level++) 
+    {
         const uint numberOfNodesPerLevelCF = builder->getNumberOfNodesCF(level);
         const uint numberOfNodesPerLevelFC = builder->getNumberOfNodesFC(level);
 
-        cout << "number of nodes CFlLevel " << level << " : " << numberOfNodesPerLevelCF << endl;
+        cout << "number of nodes CF Level " << level << " : " << numberOfNodesPerLevelCF << endl;
         cout << "number of nodes FC level " << level << " : " << numberOfNodesPerLevelFC << endl;
 
-        numberOfNodesCF += numberOfNodesPerLevelCF;
-        numberOfNodesFC += numberOfNodesPerLevelFC;
-
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         //size + memsize CF
         para->getParH(level)->K_CF = numberOfNodesPerLevelCF;
         para->getParD(level)->K_CF = para->getParH(level)->K_CF;
         para->getParH(level)->intCF.kCF = para->getParH(level)->K_CF;
         para->getParD(level)->intCF.kCF = para->getParH(level)->K_CF;
-        para->getParH(level)->mem_size_kCF = sizeof(unsigned int)* para->getParH(level)->K_CF;
-        para->getParD(level)->mem_size_kCF = sizeof(unsigned int)* para->getParD(level)->K_CF;
+        para->getParH(level)->mem_size_kCF = sizeof(uint)* para->getParH(level)->K_CF;
+        para->getParD(level)->mem_size_kCF = sizeof(uint)* para->getParD(level)->K_CF;
         para->getParH(level)->mem_size_kCF_off = sizeof(real)* para->getParH(level)->K_CF;
         para->getParD(level)->mem_size_kCF_off = sizeof(real)* para->getParD(level)->K_CF;
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -229,8 +219,8 @@ void GridGenerator::allocArrays_OffsetScale()
         para->getParD(level)->K_FC = para->getParH(level)->K_FC;
         para->getParH(level)->intFC.kFC = para->getParH(level)->K_FC;
         para->getParD(level)->intFC.kFC = para->getParH(level)->K_FC;
-        para->getParH(level)->mem_size_kFC = sizeof(unsigned int)* para->getParH(level)->K_FC;
-        para->getParD(level)->mem_size_kFC = sizeof(unsigned int)* para->getParD(level)->K_FC;
+        para->getParH(level)->mem_size_kFC = sizeof(uint)* para->getParH(level)->K_FC;
+        para->getParD(level)->mem_size_kFC = sizeof(uint)* para->getParD(level)->K_FC;
         para->getParH(level)->mem_size_kFC_off = sizeof(real)* para->getParH(level)->K_FC;
         para->getParD(level)->mem_size_kFC_off = sizeof(real)* para->getParD(level)->K_FC;
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -241,10 +231,26 @@ void GridGenerator::allocArrays_OffsetScale()
         para->cudaAllocInterfaceOffFC(level);
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         //init
+        builder->setOffsetCF(para->getParH(level)->offCF.xOffCF, para->getParH(level)->offCF.yOffCF, para->getParH(level)->offCF.zOffCF, level);
+        builder->setOffsetFC(para->getParH(level)->offFC.xOffFC, para->getParH(level)->offFC.yOffFC, para->getParH(level)->offFC.zOffFC, level);
         builder->setCFC(para->getParH(level)->intCF.ICellCFC, level);
         builder->setCFF(para->getParH(level)->intCF.ICellCFF, level);
         builder->setFCC(para->getParH(level)->intFC.ICellFCC, level);
         builder->setFCF(para->getParH(level)->intFC.ICellFCF, level);
+
+        printf("%d\n", para->getParH(level)->intCF.ICellCFC[para->getParH(level)->intCF.kCF - 1]);
+        printf("%d\n", para->getParH(level)->intCF.ICellCFF[para->getParH(level)->intCF.kCF - 1]);
+        printf("%d\n", para->getParH(level)->intFC.ICellFCC[para->getParH(level)->intFC.kFC - 1]);
+        printf("%d\n", para->getParH(level)->intFC.ICellFCF[para->getParH(level)->intFC.kFC - 1]);
+
+        printf("%f\n", para->getParH(level)->offFC.xOffFC[para->getParH(level)->intFC.kFC - 1]);
+        printf("%f\n", para->getParH(level)->offFC.yOffFC[para->getParH(level)->intFC.kFC - 1]);
+        printf("%f\n", para->getParH(level)->offFC.zOffFC[para->getParH(level)->intFC.kFC - 1]);
+        printf("%f\n", para->getParH(level)->offCF.xOffCF[para->getParH(level)->intCF.kCF - 1]);
+        printf("%f\n", para->getParH(level)->offCF.yOffCF[para->getParH(level)->intCF.kCF - 1]);
+        printf("%f\n", para->getParH(level)->offCF.zOffCF[para->getParH(level)->intCF.kCF - 1]);
+
+
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         //copy
         para->cudaCopyInterfaceCF(level);
diff --git a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
index 1cd5aad43297e363d1f6f14eb19c90f233ded639..d8d64f7718b3b3035f5593abd079a35b67d8d645 100644
--- a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
+++ b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
@@ -25,11 +25,9 @@ public:
     VF_PUBLIC GridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para);
 	VF_PUBLIC virtual ~GridGenerator();
 
-	void setUnstructuredGridBuilder(std::shared_ptr<GridBuilder> builder);
-
-	virtual void allocArrays_CoordNeighborGeo()override;
-	virtual void allocArrays_BoundaryValues()override;
-	virtual void allocArrays_BoundaryQs()override;
+	void allocArrays_CoordNeighborGeo() override;
+	void allocArrays_BoundaryValues() override;
+	void allocArrays_BoundaryQs() override;
     void allocArrays_OffsetScale() override;
 
 	virtual void setDimensions();
diff --git a/src/VirtualFluids_GPU/Output/InterfaceDebugWriter.hpp b/src/VirtualFluids_GPU/Output/InterfaceDebugWriter.hpp
index 4bd731d16043fbb15bd7c90e54476a441ba1c2ea..7e4a71018e17d4dc03dc712439d75994fe253a47 100644
--- a/src/VirtualFluids_GPU/Output/InterfaceDebugWriter.hpp
+++ b/src/VirtualFluids_GPU/Output/InterfaceDebugWriter.hpp
@@ -125,6 +125,8 @@ namespace InterfaceDebugWriter
 				double x1Neighbor = para->getParH(level)->coordX_SP[para->getParH(level)->neighborX_SP[pos]];
 				double x2Neighbor = para->getParH(level)->coordY_SP[para->getParH(level)->neighborY_SP[pos]];
 				double x3Neighbor = para->getParH(level)->coordZ_SP[para->getParH(level)->neighborZ_SP[pos]];
+                if (x1Neighbor == 0 && x2Neighbor == 0 && x3Neighbor == 0)
+                    continue;
 
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1),(float)(x2),(float)(x3) ) );
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1Neighbor),(float)(x2Neighbor),(float)(x3Neighbor) ) );
@@ -163,6 +165,8 @@ namespace InterfaceDebugWriter
 				double x1Neighbor = para->getParH(level+1)->coordX_SP[para->getParH(level+1)->neighborX_SP[pos]];
 				double x2Neighbor = para->getParH(level+1)->coordY_SP[para->getParH(level+1)->neighborY_SP[pos]];
 				double x3Neighbor = para->getParH(level+1)->coordZ_SP[para->getParH(level+1)->neighborZ_SP[pos]];
+                if (x1Neighbor == 0 && x2Neighbor == 0 && x3Neighbor == 0)
+                    continue;
 
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1),(float)(x2),(float)(x3) ) );
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1Neighbor),(float)(x2Neighbor),(float)(x3Neighbor) ) );
@@ -201,6 +205,8 @@ namespace InterfaceDebugWriter
 				double x1Neighbor = para->getParH(level)->coordX_SP[para->getParH(level)->neighborX_SP[pos]];
 				double x2Neighbor = para->getParH(level)->coordY_SP[para->getParH(level)->neighborY_SP[pos]];
 				double x3Neighbor = para->getParH(level)->coordZ_SP[para->getParH(level)->neighborZ_SP[pos]];
+                if (x1Neighbor == 0 && x2Neighbor == 0 && x3Neighbor == 0)
+                    continue;
 
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1),(float)(x2),(float)(x3) ) );
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1Neighbor),(float)(x2Neighbor),(float)(x3Neighbor) ) );
@@ -239,6 +245,8 @@ namespace InterfaceDebugWriter
 				double x1Neighbor = para->getParH(level+1)->coordX_SP[para->getParH(level+1)->neighborX_SP[pos]];
 				double x2Neighbor = para->getParH(level+1)->coordY_SP[para->getParH(level+1)->neighborY_SP[pos]];
 				double x3Neighbor = para->getParH(level+1)->coordZ_SP[para->getParH(level+1)->neighborZ_SP[pos]];
+                if (x1Neighbor == 0 && x2Neighbor == 0 && x3Neighbor == 0)
+                    continue;
 
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1),(float)(x2),(float)(x3) ) );
 				nodesVec[nodeCount++]=( makeUbTuple( (float)(x1Neighbor),(float)(x2Neighbor),(float)(x3Neighbor) ) );
diff --git a/src/VirtualFluids_GPU/Output/WriteData.cpp b/src/VirtualFluids_GPU/Output/WriteData.cpp
index 3063a74401d268af09e5b390fb310275c870e23c..39452d63d6513d2d8e43b9786ae1bf2bb312da29 100644
--- a/src/VirtualFluids_GPU/Output/WriteData.cpp
+++ b/src/VirtualFluids_GPU/Output/WriteData.cpp
@@ -75,10 +75,6 @@ void writeInit(SPtr<Parameter> para)
 		} 
 		else
 		{
-
-
-			
-
 			if (para->getUseWale())
 			{
 				UnstrucuredGridWriter::writeUnstrucuredGridLTwithTurbulentViscosity(para.get(), lev, fname);
@@ -93,9 +89,12 @@ void writeInit(SPtr<Parameter> para)
 			}
 
 			//Debug
-			//InterfaceDebugWriter::writeInterfaceLinesDebugCF(para);
-			//InterfaceDebugWriter::writeInterfaceLinesDebugCFCneighbor(para);
-			//InterfaceDebugWriter::writeInterfaceLinesDebugCFFneighbor(para);
+			InterfaceDebugWriter::writeInterfaceLinesDebugCF(para.get());
+            InterfaceDebugWriter::writeInterfaceLinesDebugFC(para.get());
+			InterfaceDebugWriter::writeInterfaceLinesDebugCFCneighbor(para.get());
+            InterfaceDebugWriter::writeInterfaceLinesDebugCFFneighbor(para.get());
+            InterfaceDebugWriter::writeInterfaceLinesDebugFCCneighbor(para.get());
+            InterfaceDebugWriter::writeInterfaceLinesDebugFCFneighbor(para.get());
 			//InterfaceDebugWriter::writeNeighborXLinesDebug(para);
 			//InterfaceDebugWriter::writeNeighborYLinesDebug(para);
 			//InterfaceDebugWriter::writeNeighborZLinesDebug(para);
diff --git a/targets/apps/HULC/main.cpp b/targets/apps/HULC/main.cpp
index 1977321b99b371892c6b8634e3880f1d73aa72c6..c23c09f78ece706c8be36c518ead72fa1736d91a 100644
--- a/targets/apps/HULC/main.cpp
+++ b/targets/apps/HULC/main.cpp
@@ -231,7 +231,6 @@ void setParameters(std::shared_ptr<Parameter> para, std::unique_ptr<input::Input
 
 void multipleLevel(const std::string& configPath)
 {
-    
     SPtr<LevelGridBuilder> gridBuilder(new LevelGridBuilder());
     gridBuilder->addGrid(20, 0, -10, 80, 60, 50, 1.0, "cpu", "D3Q27");
     gridBuilder->addGrid(35.25, 3.25, -4.75, 70.75, 40.75, 25.75, 0.5, "cpu", "D3Q27");
@@ -239,7 +238,7 @@ void multipleLevel(const std::string& configPath)
 
     //gridBuilder->meshGeometry("D:/GRIDGENERATION/STL/circleBinaer.stl", 1);
     //gridBuilder->meshGeometry("D:/GRIDGENERATION/STL/circleBinaer.stl", 0);
-    // gridBuilder->writeGridToVTK("D:/GRIDGENERATION/gridTest_level_1", 1);
+    //gridBuilder->writeGridToVTK("D:/GRIDGENERATION/gridTest_level_1", 1);
     //gridBuilder->writeGridToVTK("D:/GRIDGENERATION/gridTest_level_0", 0);
 
     SPtr<Parameter> para = Parameter::make();