From 4d6865b6f223b021ed6a1b564bc4924190980aac Mon Sep 17 00:00:00 2001
From: "LEGOLAS\\lenz" <lenz@irmb.tu-bs.de>
Date: Fri, 21 Sep 2018 18:03:33 +0200
Subject: [PATCH] Updates the Simulation File Writer - NOT WELL TESTED YET

---
 .../BoundaryConditions/BoundaryCondition.cpp  |   9 +-
 .../BoundaryConditions/BoundaryCondition.h    |  19 +-
 .../grid/BoundaryConditions/Side.cpp          |  66 +++--
 .../grid/BoundaryConditions/Side.h            |  39 +++
 .../grid/GridBuilder/GridBuilder.h            |  11 +-
 .../grid/GridBuilder/LevelGridBuilder.cpp     |  22 +-
 .../grid/GridBuilder/LevelGridBuilder.h       |   7 +-
 src/GridGenerator/grid/GridImp.cu             |   3 +-
 .../SimulationFileWriter.cpp                  | 239 +++++++++++++++---
 .../SimulationFileWriter.h                    |  11 +-
 .../GridReaderFiles/GridReader.cpp            |   1 +
 .../GridReaderGenerator/GridGenerator.cpp     |   4 +-
 targets/apps/HULC/main.cpp                    |  60 ++---
 13 files changed, 391 insertions(+), 100 deletions(-)

diff --git a/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.cpp b/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.cpp
index 5a530af15..c558198bf 100644
--- a/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.cpp
+++ b/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.cpp
@@ -1 +1,8 @@
-#include "BoundaryCondition.h"
\ No newline at end of file
+#include "BoundaryCondition.h"
+
+#include "Side.h"
+
+bool BoundaryCondition::isSide( SideType side ) const
+{
+    return this->side->whoAmI() == side;
+}
\ No newline at end of file
diff --git a/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.h b/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.h
index bccbde0d4..3fc9494ef 100644
--- a/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.h
+++ b/src/GridGenerator/grid/BoundaryConditions/BoundaryCondition.h
@@ -8,15 +8,20 @@
 #include "grid/NodeValues.h"
 
 class Side;
+enum class SideType;
 
 class BoundaryCondition
 {
 public:
     std::vector<uint> indices;
     SPtr<Side> side;
+    std::vector<std::vector<real> > qs;
 
     virtual char getType() const = 0;
 
+    bool isSide( SideType side ) const;
+
+    real getQ( uint index, uint dir ){ return this->qs[index][dir]; }
 };
 
 class PressureBoundaryCondition : public BoundaryCondition
@@ -42,6 +47,11 @@ public:
     {
         return BC_PRESSURE;
     }
+
+    real getRho()
+    {
+        return this->rho;
+    }
 };
 
 class VelocityBoundaryCondition : public BoundaryCondition
@@ -64,6 +74,10 @@ public:
     {
         return BC_VELOCITY;
     }
+
+    real getVx() { return this->vx; }
+    real getVy() { return this->vy; }
+    real getVz() { return this->vz; }
 };
 
 
@@ -76,7 +90,6 @@ public:
     }
 
     real vx, vy, vz;
-    std::vector<std::vector<real> > qs;
 private:
     GeometryBoundaryCondition()
     {
@@ -88,6 +101,10 @@ public:
     {
         return BC_SOLID;
     }
+
+    real getVx() { return this->vx; }
+    real getVy() { return this->vy; }
+    real getVz() { return this->vz; }
 };
 
 
diff --git a/src/GridGenerator/grid/BoundaryConditions/Side.cpp b/src/GridGenerator/grid/BoundaryConditions/Side.cpp
index 895f86c79..de6ef1a36 100644
--- a/src/GridGenerator/grid/BoundaryConditions/Side.cpp
+++ b/src/GridGenerator/grid/BoundaryConditions/Side.cpp
@@ -24,6 +24,8 @@ void Side::addIndices(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition
                 grid->setFieldEntry(index, boundaryCondition->getType());
                 boundaryCondition->indices.push_back(index);
                 setPressureNeighborIndices(boundaryCondition, grid, index);
+
+                setQs(grid, boundaryCondition, index);
             }
         }
     }
@@ -53,6 +55,31 @@ void Side::setPressureNeighborIndices(SPtr<BoundaryCondition> boundaryCondition,
     }
 }
 
+void Side::setQs(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, uint index)
+{
+
+    std::vector<real> qNode(grid->getEndDirection() + 1);
+
+    for (int dir = 0; dir <= grid->getEndDirection(); dir++)
+    {
+        real x,y,z;
+        grid->transIndexToCoords( index, x, y, z );
+
+        x += grid->getDirection()[dir * DIMENSION + 0] * grid->getDelta();
+        y += grid->getDirection()[dir * DIMENSION + 1] * grid->getDelta();
+        z += grid->getDirection()[dir * DIMENSION + 2] * grid->getDelta();
+
+        uint neighborIndex = grid->transCoordToIndex( x, y, z );
+
+        if( grid->getFieldEntry(neighborIndex) == STOPPER_OUT_OF_GRID_BOUNDARY )
+            qNode[dir] = 0.5;
+        else
+            qNode[dir] = -1.0;
+    }
+
+    boundaryCondition->qs.push_back(qNode);
+}
+
 uint Side::getIndex(SPtr<Grid> grid, std::string coord, real constant, real v1, real v2)
 {
     if (coord == "x")
@@ -65,38 +92,41 @@ uint Side::getIndex(SPtr<Grid> grid, std::string coord, real constant, real v1,
 }
 
 
-void Geometry::addIndices(std::vector<SPtr<Grid> > grid, uint level, SPtr<BoundaryCondition> boundaryCondition)
+void Geometry::addIndices(std::vector<SPtr<Grid> > grids, uint level, SPtr<BoundaryCondition> boundaryCondition)
 {
     auto geometryBoundaryCondition = std::dynamic_pointer_cast<GeometryBoundaryCondition>(boundaryCondition);
 
-    std::vector<real> qNode(27);
+    std::vector<real> qNode(grids[level]->getEndDirection() + 1);
     bool qFound = false;
 
-    for (uint i = 0; i < grid[level]->getSize(); i++)
+    for (uint index = 0; index < grids[level]->getSize(); index++)
     {
-        if (grid[level]->getFieldEntry(i) != BC_SOLID)
+        if (grids[level]->getFieldEntry(index) != BC_SOLID)
             continue;
 
-        for (int dir = 0; dir <= grid[level]->getEndDirection(); dir++)
+        for (int dir = 0; dir <= grids[level]->getEndDirection(); dir++)
         {
-            //const int qIndex = dir * grid[level]->getSize() + i;
-            //const real q = grid[level]->getDistribution()[qIndex];
-
-			const real q = grid[level]->getQValue(i, dir);
+			const real q = grids[level]->getQValue(index, dir);
 
             qNode[dir] = q;
-            //if (vf::Math::greaterEqual(q, 0.0))
-            //    qFound = true;
-            ////else
-            ////    qNode[dir] = -1.0;
-        }
 
-        //if (qFound)
-        {
-            geometryBoundaryCondition->indices.push_back(i);
-            geometryBoundaryCondition->qs.push_back(qNode);
+            // also the neighbor if any Qs are required
+            real x,y,z;
+            grids[level]->transIndexToCoords( index, x, y, z );
+
+            x += grids[level]->getDirection()[dir * DIMENSION + 0] * grids[level]->getDelta();
+            y += grids[level]->getDirection()[dir * DIMENSION + 1] * grids[level]->getDelta();
+            z += grids[level]->getDirection()[dir * DIMENSION + 2] * grids[level]->getDelta();
+
+            uint neighborIndex = grids[level]->transCoordToIndex( x, y, z );
+
+            if( grids[level]->getFieldEntry(neighborIndex) == STOPPER_OUT_OF_GRID_BOUNDARY )
+                qNode[dir] = 0.5;
         }
 
+        geometryBoundaryCondition->indices.push_back(index);
+        geometryBoundaryCondition->qs.push_back(qNode);
+
         qFound = false;
     }
 }
diff --git a/src/GridGenerator/grid/BoundaryConditions/Side.h b/src/GridGenerator/grid/BoundaryConditions/Side.h
index 0ad824a41..d7190ea5c 100644
--- a/src/GridGenerator/grid/BoundaryConditions/Side.h
+++ b/src/GridGenerator/grid/BoundaryConditions/Side.h
@@ -36,12 +36,16 @@ public:
     virtual int getCoordinate() const = 0;
     virtual int getDirection() const = 0;
 
+    virtual SideType whoAmI() const = 0;
+
 protected:
     static void addIndices(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, std::string coord, real constant,
                            real startInner, real endInner, real startOuter, real endOuter);
 
     static void setPressureNeighborIndices(SPtr<BoundaryCondition> boundaryCondition, SPtr<Grid> grid, const uint index);
 
+    static void setQs(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, uint index);
+
 private:
     static uint getIndex(SPtr<Grid> grid, std::string coord, real constant, real v1, real v2);
 };
@@ -60,6 +64,11 @@ public:
     {
         return NEGATIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::GEOMETRY;
+    }
 };
 
 class MX : public Side
@@ -76,6 +85,11 @@ public:
     {
         return NEGATIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::MX;
+    }
 };
 
 class PX : public Side
@@ -92,6 +106,11 @@ public:
     {
         return POSITIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::PX;
+    }
 };
 
 
@@ -109,6 +128,11 @@ public:
     {
         return NEGATIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::MY;
+    }
 };
 
 class PY : public Side
@@ -125,6 +149,11 @@ public:
     {
         return POSITIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::PY;
+    }
 };
 
 
@@ -142,6 +171,11 @@ public:
     {
         return NEGATIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::MZ;
+    }
 };
 
 class PZ : public Side
@@ -158,6 +192,11 @@ public:
     {
         return POSITIVE_DIR;
     }
+
+    SideType whoAmI() const override
+    {
+        return SideType::PZ;
+    }
 };
 
 
diff --git a/src/GridGenerator/grid/GridBuilder/GridBuilder.h b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
index 02453626f..1a4ce6d6f 100644
--- a/src/GridGenerator/grid/GridBuilder/GridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/GridBuilder.h
@@ -26,9 +26,12 @@ class ArrowTransformator;
 class PolyDataWriterWrapper;
 
 class BoundingBox;
-
 class Grid;
 
+enum class SideType;
+
+class BoundaryCondition;
+
 class GridBuilder
 {
 public:
@@ -55,8 +58,8 @@ public:
     virtual uint getNumberOfNodesFC(int level) = 0;
     virtual void getGridInterfaceIndices(uint* iCellCfc, uint* iCellCff, uint* iCellFcc, uint* iCellFcf, int level) const = 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;
+    virtual void getOffsetFC(real* xOffCf, real* yOffCf, real* zOffCf, int level) = 0;
+    virtual void getOffsetCF(real* xOffFc, real* yOffFc, real* zOffFc, int level) = 0;
 
     virtual uint getVelocitySize(int level) const = 0;
     virtual void getVelocityValues(real* vx, real* vy, real* vz, int* indices, int level) const = 0;
@@ -71,6 +74,8 @@ public:
     virtual bool hasGeometryValues() const = 0;
     virtual void getGeometryValues(real* vx, real* vy, real* vz, int level) const = 0;
 
+    virtual SPtr<BoundaryCondition> getBoundaryCondition( SideType side, uint level ) const = 0;
+
 };
 
 #endif
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
index 42c598d77..5accee3ea 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
@@ -196,7 +196,7 @@ void LevelGridBuilder::getGridInterfaceIndices(uint* iCellCfc, uint* iCellCff, u
     this->grids[level]->getGridInterfaceIndices(iCellCfc, iCellCff, iCellFcc, iCellFcf);
 }
 
-void LevelGridBuilder::setOffsetFC(real * xOffFC, real * yOffFC, real * zOffFC, int level)
+void LevelGridBuilder::getOffsetFC(real * xOffFC, real * yOffFC, real * zOffFC, int level)
 {
     for (uint i = 0; i < getNumberOfNodesFC(level); i++)
     {
@@ -208,7 +208,7 @@ void LevelGridBuilder::setOffsetFC(real * xOffFC, real * yOffFC, real * zOffFC,
     }
 }
 
-void LevelGridBuilder::setOffsetCF(real * xOffCF, real * yOffCF, real * zOffCF, int level)
+void LevelGridBuilder::getOffsetCF(real * xOffCF, real * yOffCF, real * zOffCF, int level)
 {
     for (uint i = 0; i < getNumberOfNodesCF(level); i++)
     {
@@ -434,3 +434,21 @@ void LevelGridBuilder::writeArrows(std::string fileName) const
 {
     QLineWriter::writeArrows(fileName, boundaryConditions[getNumberOfGridLevels() - 1]->geometryBoundaryCondition, grids[getNumberOfGridLevels() - 1]);
 }
+
+VF_PUBLIC SPtr<BoundaryCondition> LevelGridBuilder::getBoundaryCondition(SideType side, uint level) const
+{
+    for( auto bc : this->boundaryConditions[level]->pressureBoundaryConditions )
+        if( bc->isSide(side) )
+            return bc;
+    
+    for( auto bc : this->boundaryConditions[level]->velocityBoundaryConditions )
+        if( bc->isSide(side) )
+            return bc;
+
+    auto bc = this->boundaryConditions[level]->geometryBoundaryCondition;
+    
+    if( bc && bc->isSide(side) )
+        return bc;
+
+    return nullptr;
+}
diff --git a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
index eacc8b3a8..96c3f4de4 100644
--- a/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
+++ b/src/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
@@ -77,6 +77,8 @@ public:
 
     VF_PUBLIC void writeArrows(std::string fileName) const;
 
+    VF_PUBLIC SPtr<BoundaryCondition> getBoundaryCondition( SideType side, uint level ) const override;
+
 protected:
     
 
@@ -96,7 +98,6 @@ protected:
     std::vector<std::shared_ptr<Grid> > grids;
     std::vector<SPtr<BoundaryConditions> > boundaryConditions;
 
-
     void checkLevel(int level);
 
 protected:
@@ -124,8 +125,8 @@ public:
 
     VF_PUBLIC void getGridInterfaceIndices(uint* iCellCfc, uint* iCellCff, uint* iCellFcc, uint* iCellFcf, int level) const 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;
+    VF_PUBLIC void getOffsetFC(real* xOffCf, real* yOffCf, real* zOffCf, int level) override;
+    VF_PUBLIC void getOffsetCF(real* xOffFc, real* yOffFc, real* zOffFc, int level) override;
 
 };
 
diff --git a/src/GridGenerator/grid/GridImp.cu b/src/GridGenerator/grid/GridImp.cu
index bc614acff..258f052af 100644
--- a/src/GridGenerator/grid/GridImp.cu
+++ b/src/GridGenerator/grid/GridImp.cu
@@ -1511,7 +1511,7 @@ void GridImp::getGridInterfaceIndices(uint* iCellCfc, uint* iCellCff, uint* iCel
 void GridImp::getGridInterface(uint* gridInterfaceList, const uint* oldGridInterfaceList, uint size)
 {
     for (uint i = 0; i < size; i++)
-        gridInterfaceList[i] = oldGridInterfaceList[i] + 1;
+        gridInterfaceList[i] = oldGridInterfaceList[i] + 1; // + 1 for numbering shift between GridGenerator and VF_GPU
 }
 
 #define GEOFLUID 19
@@ -1536,6 +1536,7 @@ HOST void GridImp::getNodeValues(real *xCoords, real *yCoords, real *zCoords, ui
         real x, y, z;
         this->transIndexToCoords(i, x, y, z);
 
+        // + 1 for numbering shift between GridGenerator and VF_GPU
         const uint neighborXIndex        = uint(this->neighborIndexX[i] + 1);
         const uint neighborYIndex        = uint(this->neighborIndexY[i] + 1);
         const uint neighborZIndex        = uint(this->neighborIndexZ[i] + 1);
diff --git a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
index a246fb5b0..d84caa60f 100644
--- a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
+++ b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
@@ -13,6 +13,8 @@
 
 #include <GridGenerator/grid/GridBuilder/GridBuilder.h>
 
+#include <GridGenerator/grid/BoundaryConditions/Side.h>
+#include <GridGenerator/grid/BoundaryConditions/BoundaryCondition.h>
 
 /*#################################################################################*/
 /*---------------------------------public methods----------------------------------*/
@@ -41,11 +43,11 @@ void SimulationFileWriter::write(SPtr<GridBuilder> builder, FILEFORMAT format)
     const uint numberOfLevel = builder->getNumberOfGridLevels();
     openFiles();
     writeLevel(numberOfLevel);
-    auto qs = createBCVectors(builder->getGrid(0));
+    //auto qs = createBCVectors(builder->getGrid(0));
 
     for (uint level = 0; level < numberOfLevel; level++)
     {
-        writeLevelSize(builder->getNumberOfNodes(level), qs);
+        writeLevelSize(builder->getNumberOfNodes(level));
         writeCoordFiles(builder, level, format);
 
         if (level < numberOfLevel - 1)
@@ -53,8 +55,10 @@ void SimulationFileWriter::write(SPtr<GridBuilder> builder, FILEFORMAT format)
             writeLevelSizeGridInterface(builder->getNumberOfNodesCF(level), builder->getNumberOfNodesFC(level));
             writeGridInterfaceToFile(builder, level);
         }
-        writeBoundaryQsFile(qs);
     }
+
+    writeBoundaryQsFile(builder);
+
     closeFiles();
 }
 
@@ -127,15 +131,15 @@ void SimulationFileWriter::writeLevel(uint numberOfLevels)
     offsetVecCF_File << level << "\n";
     offsetVecFC_File << level << "\n";
 
-    const std::string geoRB = "noSlip\n";
+    //const std::string geoRB = "noSlip\n";
 
-    for (int rb = 0; rb < QFILES; rb++) {
-        *qStreams[rb] << level << "\n";
-        *valueStreams[rb] << geoRB << level << "\n";
-    }
+    //for (int rb = 0; rb < QFILES; rb++) {
+    //    *qStreams[rb] << level << "\n";
+    //    *valueStreams[rb] << geoRB << level << "\n";
+    //}
 }
 
-void SimulationFileWriter::writeLevelSize(uint numberOfNodes, std::vector<std::vector<std::vector<real> > > qFiles)
+void SimulationFileWriter::writeLevelSize(uint numberOfNodes)
 {
     const std::string zeroIndex = "0 ";
     const std::string zeroGeo = "16 ";
@@ -148,12 +152,12 @@ void SimulationFileWriter::writeLevelSize(uint numberOfNodes, std::vector<std::v
     zNeighborFile << numberOfNodes << "\n" << zeroIndex;
     geoVecFile << numberOfNodes << "\n" << zeroGeo;
 
-    const std::string geoRB = "noSlip\n";
+    //const std::string geoRB = "noSlip\n";
 
-    for (int rb = 0; rb < QFILES; rb++) {
-        *qStreams[rb] << qFiles[rb].size() << "\n";
-        *valueStreams[rb] << geoRB << qFiles[rb].size() << "\n";
-    }
+    //for (int rb = 0; rb < QFILES; rb++) {
+    //    *qStreams[rb] << qFiles[rb].size() << "\n";
+    //    *valueStreams[rb] << geoRB << qFiles[rb].size() << "\n";
+    //}
 }
 
 void SimulationFileWriter::writeLevelSizeGridInterface(uint sizeCF, uint sizeFC)
@@ -171,6 +175,16 @@ void SimulationFileWriter::writeCoordFiles(SPtr<GridBuilder> builder, uint level
 {
     for (uint index = 0; index < builder->getNumberOfNodes(level); index++)
         writeCoordsNeighborsGeo(builder, index, level, format);
+
+    xCoordFile << "\n";
+    yCoordFile << "\n";
+    zCoordFile << "\n";
+
+    xNeighborFile << "\n";
+    yNeighborFile << "\n";
+    zNeighborFile << "\n";
+
+    geoVecFile << "\n";
 }
 
 void SimulationFileWriter::writeCoordsNeighborsGeo(SPtr<GridBuilder> builder, int index, uint level, FILEFORMAT format)
@@ -179,7 +193,16 @@ void SimulationFileWriter::writeCoordsNeighborsGeo(SPtr<GridBuilder> builder, in
     if (grid->getSparseIndex(index) == -1)
         return;
 
-    int type = grid->getFieldEntry(index) == FLUID ? 19 : 16;
+    // Lenz: in the GPU code all nodes that perform collisions have to be fluid = 19
+    bool isStopper = grid->getFieldEntry(index) == STOPPER_SOLID                || 
+                     grid->getFieldEntry(index) == STOPPER_OUT_OF_GRID          || 
+                     grid->getFieldEntry(index) == STOPPER_OUT_OF_GRID_BOUNDARY || 
+                     grid->getFieldEntry(index) == STOPPER_COARSE_UNDER_FINE;
+    int type = !isStopper ? 19 : 16;
+
+    // old code from Soeren P.
+    //int type = grid->getFieldEntry(index) == FLUID ? 19 : 16;
+
     real x, y, z;
     grid->transIndexToCoords(index, x, y, z);
 
@@ -189,6 +212,7 @@ void SimulationFileWriter::writeCoordsNeighborsGeo(SPtr<GridBuilder> builder, in
         yCoordFile.write((char*)&y, sizeof(double));
         zCoordFile.write((char*)&z, sizeof(double));
 
+        // + 1 for numbering shift between GridGenerator and VF_GPU
         xNeighborFile.write((char*)(&grid->getNeighborsX()[index] + 1), sizeof(unsigned int));
         yNeighborFile.write((char*)(&grid->getNeighborsY()[index] + 1), sizeof(unsigned int));
         zNeighborFile.write((char*)(&grid->getNeighborsZ()[index] + 1), sizeof(unsigned int));
@@ -201,6 +225,7 @@ void SimulationFileWriter::writeCoordsNeighborsGeo(SPtr<GridBuilder> builder, in
         yCoordFile << y << " ";
         zCoordFile << z << " ";
 
+        // + 1 for numbering shift between GridGenerator and VF_GPU
         xNeighborFile << (grid->getNeighborsX()[index] + 1) << " ";
         yNeighborFile << (grid->getNeighborsY()[index] + 1) << " ";
         zNeighborFile << (grid->getNeighborsZ()[index] + 1) << " ";
@@ -214,34 +239,79 @@ void SimulationFileWriter::writeGridInterfaceToFile(SPtr<GridBuilder> builder, u
     const uint numberOfNodesCF = builder->getNumberOfNodesCF(level);
     const uint numberOfNodesFC = builder->getNumberOfNodesFC(level);
 
-    uint* cf_coarse = new uint[numberOfNodesCF];
-    uint* cf_fine = new uint[numberOfNodesCF];
-    uint* fc_coarse = new uint[numberOfNodesFC];
-    uint* fc_fine = new uint[numberOfNodesFC];
+    {
+        uint* cf_coarse = new uint[numberOfNodesCF];
+        uint* cf_fine = new uint[numberOfNodesCF];
+        uint* fc_coarse = new uint[numberOfNodesFC];
+        uint* fc_fine = new uint[numberOfNodesFC];
 
-    builder->getGridInterfaceIndices(cf_coarse, cf_fine, fc_coarse, fc_fine, level);
+        builder->getGridInterfaceIndices(cf_coarse, cf_fine, fc_coarse, fc_fine, level);
 
-    if(numberOfNodesCF > 0)
-    {
-        writeGridInterfaceToFile(numberOfNodesCF, scaleCF_coarse_File, cf_coarse, scaleCF_fine_File, cf_fine, offsetVecCF_File);
+        if (numberOfNodesCF > 0)
+        {
+            writeGridInterfaceToFile(numberOfNodesCF, scaleCF_coarse_File, cf_coarse, scaleCF_fine_File, cf_fine);
+        }
+
+        if (numberOfNodesFC > 0)
+        {
+            writeGridInterfaceToFile(numberOfNodesFC, scaleFC_coarse_File, fc_coarse, scaleFC_fine_File, fc_fine);
+        }
+
+        delete [] cf_coarse;
+        delete [] cf_fine;
+        delete [] fc_coarse;
+        delete [] fc_fine;
     }
 
-    if (numberOfNodesFC > 0)
     {
-        writeGridInterfaceToFile(numberOfNodesFC, scaleFC_coarse_File, fc_coarse, scaleFC_fine_File, fc_fine, offsetVecFC_File);
+        real* cf_offset_X = new real[numberOfNodesCF];
+        real* cf_offset_Y = new real[numberOfNodesCF];
+        real* cf_offset_Z = new real[numberOfNodesCF];
+
+        real* fc_offset_X = new real[numberOfNodesFC];
+        real* fc_offset_Y = new real[numberOfNodesFC];
+        real* fc_offset_Z = new real[numberOfNodesFC];
+
+        builder->getOffsetCF(cf_offset_X, cf_offset_Y, cf_offset_Z, level);
+        builder->getOffsetFC(fc_offset_X, fc_offset_Y, fc_offset_Z, level);
+
+        if (numberOfNodesCF > 0)
+        {
+            writeGridInterfaceOffsetToFile(numberOfNodesCF, offsetVecCF_File, cf_offset_X, cf_offset_Y, cf_offset_Z);
+        }
+
+        if (numberOfNodesFC > 0)
+        {
+            writeGridInterfaceOffsetToFile(numberOfNodesCF, offsetVecFC_File, fc_offset_X, fc_offset_Y, fc_offset_Z);
+        }
+
+        delete[] cf_offset_X;
+        delete[] cf_offset_Y;
+        delete[] cf_offset_Z;
+
+        delete[] fc_offset_X;
+        delete[] fc_offset_Y;
+        delete[] fc_offset_Z;
     }
 }
 
-void SimulationFileWriter::writeGridInterfaceToFile(const uint numberOfNodes, std::ofstream& coarseFile, uint* coarse, std::ofstream& fineFile, uint* fine, std::ofstream& offsetFile)
+void SimulationFileWriter::writeGridInterfaceToFile(const uint numberOfNodes, std::ofstream& coarseFile, uint* coarse, std::ofstream& fineFile, uint* fine)
 {
     for (uint index = 0; index < numberOfNodes; index++)
     {
-        coarseFile << coarse[index] + 1 << " ";
-        fineFile << fine[index] + 1 << " ";
-        offsetFile << 0 << " " << 0 << " " << 0 << " ";
+        coarseFile << coarse[index] << " \n";
+        fineFile << fine[index] << " \n";
     }
     coarseFile << "\n";
     fineFile << "\n";
+}
+
+void SimulationFileWriter::writeGridInterfaceOffsetToFile(uint numberOfNodes, std::ofstream & offsetFile, real* offset_X, real* offset_Y, real* offset_Z)
+{
+    for (uint index = 0; index < numberOfNodes; index++)
+    {
+        offsetFile << offset_X[index] << " " << offset_Y[index] << " " << offset_Z[index] << " \n";
+    }
     offsetFile << "\n";
 }
 
@@ -257,9 +327,9 @@ std::vector<std::vector<std::vector<real> > > SimulationFileWriter::createBCVect
     for (uint i = 0; i < grid->getSize(); i++)
     {
         real x, y, z;
-        grid->transIndexToCoords(grid->getSparseIndex(i), x, y, z);
+        grid->transIndexToCoords(i, x, y, z);
 
-        if (grid->getFieldEntry(grid->getSparseIndex(i)) == BC_SOLID) addShortQsToVector(i, qs, grid); //addQsToVector(i, qs, grid);
+        if (grid->getFieldEntry(i) == BC_SOLID) addShortQsToVector(i, qs, grid); //addQsToVector(i, qs, grid);
         //if (x == 0 && y < grid->getNumberOfNodesY() - 1 && z < grid->getNumberOfNodesZ() - 1) fillRBForNode(i, 0, -1, INLETQS, qs, grid);
         //if (x == grid->getNumberOfNodesX() - 2 && y < grid->getNumberOfNodesY() - 1 && z < grid->getNumberOfNodesZ() - 1) fillRBForNode(i, 0, 1, OUTLETQS, qs, grid);
 
@@ -341,13 +411,40 @@ void SimulationFileWriter::fillRBForNode(int index, int direction, int direction
 }
 
 
-void SimulationFileWriter::writeBoundaryQsFile(std::vector<std::vector<std::vector<real> > > qFiles)
+void SimulationFileWriter::writeBoundaryQsFile(SPtr<GridBuilder> builder)
 {
-    for (int rb = 0; rb < QFILES; rb++) {
-        for (int index = 0; index < qFiles[rb].size(); index++) {
-            //writeBoundary(qFiles[rb][index], rb);
-			writeBoundaryShort(qFiles[rb][index], rb);
-		}
+    // old code of Soeren P.
+  //  for (int rb = 0; rb < QFILES; rb++) {
+  //      for (int index = 0; index < qFiles[rb].size(); index++) {
+  //          //writeBoundary(qFiles[rb][index], rb);
+		//	writeBoundaryShort(qFiles[rb][index], rb);
+		//}
+  //  }
+
+    SideType sides[] = {SideType::MX, SideType::PX, SideType::PZ, SideType::MZ, SideType::MY, SideType::PY, SideType::GEOMETRY};
+
+    for (int side = 0; side < QFILES; side++) {
+
+        for (uint level = 0; level < builder->getNumberOfGridLevels(); level++) {
+            
+            auto bc = builder->getBoundaryCondition( sides[side], level );
+
+            if( !bc ) continue;
+
+            if( level == 0 ){
+            
+                if( bc->getType() == BC_PRESSURE ) *valueStreams[side] << "pressure\n";
+                if( bc->getType() == BC_VELOCITY ) *valueStreams[side] << "velocity\n";
+                if( bc->getType() == BC_SOLID    ) *valueStreams[side] << "noSlip\n";
+                if( bc->getType() == BC_SLIP     ) *valueStreams[side] << "slip\n";
+                if( bc->getType() == BC_OUTFLOW  ) *valueStreams[side] << "outflow\n";
+
+                *valueStreams[side] << builder->getNumberOfGridLevels() - 1 << "\n";
+                *qStreams[side]     << builder->getNumberOfGridLevels() - 1 << "\n";
+            }
+
+            writeBoundaryShort( builder->getGrid(level), bc, side );
+        }
     }
 }
 
@@ -382,6 +479,74 @@ void SimulationFileWriter::writeBoundaryShort(std::vector<real> boundary, int rb
 	*valueStreams[rb] << "\n";
 }
 
+void SimulationFileWriter::writeBoundaryShort(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, uint side)
+{
+    uint numberOfBoundaryNodes = boundaryCondition->indices.size();
+
+    *valueStreams[side] << numberOfBoundaryNodes << "\n";
+    *qStreams[side]     << numberOfBoundaryNodes << "\n";
+
+    for( uint index = 0; index < numberOfBoundaryNodes; index++ ){
+    
+        // + 1 for numbering shift between GridGenerator and VF_GPU
+        *valueStreams[side] << grid->getSparseIndex( boundaryCondition->indices[index] ) + 1 << " ";
+        *qStreams[side]     << grid->getSparseIndex( boundaryCondition->indices[index] ) + 1 << " ";
+
+        {
+            uint32_t key = 0;
+
+            for (int dir = 26; dir >= 0; dir--)
+            {
+                real q = boundaryCondition->getQ(index,dir);
+                if (q > 0) {
+                    key += (uint32_t)pow(2, 26 - dir);
+                }
+            }
+
+            *qStreams[side] << key << " ";
+
+            for (int dir = 26; dir >= 0; dir--)
+            {
+                real q = boundaryCondition->qs[index][dir];
+                if (q > 0) {
+                    *qStreams[side] << std::fixed << std::setprecision(16) << q << " ";
+                }
+            }
+
+            *qStreams[side] << "\n";
+        }
+
+        if( boundaryCondition->getType() == BC_PRESSURE )
+        {
+            auto bcPressure = dynamic_cast< PressureBoundaryCondition* >( boundaryCondition.get() );
+
+            *valueStreams[side] << bcPressure->getRho() << " ";
+            *valueStreams[side] << bcPressure->neighborIndices[index] << " ";
+        }
+
+        if( boundaryCondition->getType() == BC_VELOCITY )
+        {
+            auto bcVelocity = dynamic_cast< VelocityBoundaryCondition* >( boundaryCondition.get() );
+
+            *valueStreams[side] << bcVelocity->getVx() << " ";
+            *valueStreams[side] << bcVelocity->getVy() << " ";
+            *valueStreams[side] << bcVelocity->getVz() << " ";
+        }
+
+        if( boundaryCondition->getType() == BC_SOLID )
+        {
+            auto bcGeometry = dynamic_cast< GeometryBoundaryCondition* >( boundaryCondition.get() );
+
+            *valueStreams[side] << bcGeometry->getVx() << " ";
+            *valueStreams[side] << bcGeometry->getVy() << " ";
+            *valueStreams[side] << bcGeometry->getVz() << " ";
+        }
+
+        *valueStreams[side] << "\n";
+    }
+    
+}
+
 void SimulationFileWriter::closeFiles()
 {
     xCoordFile.close();
diff --git a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
index d5d14b114..8027a54de 100644
--- a/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
+++ b/src/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
@@ -15,6 +15,7 @@
 class UnstructuredGridBuilder;
 class GridBuilder;
 class Grid;
+class BoundaryCondition;
 
 enum class FILEFORMAT
 {
@@ -30,19 +31,23 @@ private:
     static void write(SPtr<GridBuilder> builder, FILEFORMAT format);
     static void openFiles();
     static void writeLevel(uint numberOfLevels);
-    static void writeLevelSize(uint numberOfNodes, std::vector<std::vector<std::vector<real> > > qFiles);
+    static void writeLevelSize(uint numberOfNodes);
     static void writeCoordFiles(SPtr<GridBuilder> builder, uint level, FILEFORMAT format);
     static void writeCoordsNeighborsGeo(SPtr<GridBuilder> builder, int index, uint level, FILEFORMAT format);
+
     static void writeLevelSizeGridInterface(uint sizeCF, uint sizeFC);
     static void writeGridInterfaceToFile(SPtr<GridBuilder> builder, uint level);
-    static void writeGridInterfaceToFile(uint numberOfNodes, std::ofstream& coarseFile, uint* coarse, std::ofstream& fineFile, uint* fine, std::ofstream& offsetFile);
-    static void writeBoundaryQsFile(std::vector<std::vector<std::vector<real> > > qFiles);
+    static void writeGridInterfaceToFile(uint numberOfNodes, std::ofstream& coarseFile, uint* coarse, std::ofstream& fineFile, uint* fine);
+    static void writeGridInterfaceOffsetToFile(uint numberOfNodes, std::ofstream& offsetFile, real* cf_offset_X, real* cf_offset_Y, real* cf_offset_Z);
+
+    static void writeBoundaryQsFile(SPtr<GridBuilder> builder);
     static std::vector<std::vector<std::vector<real> > > createBCVectors(SPtr<Grid> grid);
     static void addShortQsToVector(int index, std::vector<std::vector<std::vector<real> > > &qs, SPtr<Grid> grid);
     static void addQsToVector(int index, std::vector<std::vector<std::vector<real> > > &qs, SPtr<Grid> grid);
     static void fillRBForNode(int index, int direction, int directionSign, int rb, std::vector<std::vector<std::vector<real> > > &qs, SPtr<Grid> grid);
     static void writeBoundary(std::vector<real> boundary, int rb);
 	static void writeBoundaryShort(std::vector<real> boundary, int rb);
+	static void writeBoundaryShort(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, uint side);
 	static void closeFiles();
 
 
diff --git a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
index 4b3b7f902..e1614f9bd 100644
--- a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
+++ b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
@@ -81,6 +81,7 @@ void GridReader::allocArrays_CoordNeighborGeo()
 {
 	std::cout << "-----Config Arrays Coord, Neighbor, Geo------" << std::endl;
 
+    // Lenz: The first parameter in the CoordNeighborGeoV constructur is the file
 	CoordNeighborGeoV coordX(para->getcoordX(), binaer, true);
 	CoordNeighborGeoV coordY(para->getcoordY(), binaer, true);
 	CoordNeighborGeoV coordZ(para->getcoordZ(), binaer, true);
diff --git a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
index 43c5b7e86..08bc75c3f 100644
--- a/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
+++ b/src/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
@@ -530,8 +530,8 @@ 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->getOffsetCF(para->getParH(level)->offCF.xOffCF, para->getParH(level)->offCF.yOffCF, para->getParH(level)->offCF.zOffCF, level);
+        builder->getOffsetFC(para->getParH(level)->offFC.xOffFC, para->getParH(level)->offFC.yOffFC, para->getParH(level)->offFC.zOffFC, level);
         builder->getGridInterfaceIndices(para->getParH(level)->intCF.ICellCFC, para->getParH(level)->intCF.ICellCFF, para->getParH(level)->intFC.ICellFCC, para->getParH(level)->intFC.ICellFCF, level);
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         //copy
diff --git a/targets/apps/HULC/main.cpp b/targets/apps/HULC/main.cpp
index a1d9d29e5..1398c4cbf 100644
--- a/targets/apps/HULC/main.cpp
+++ b/targets/apps/HULC/main.cpp
@@ -277,34 +277,34 @@ void multipleLevel(const std::string& configPath)
     // DrivAer
     //////////////////////////////////////////////////////////////////////////
 
-	real dx = 0.2;
-	real vx = 0.05;
+	//real dx = 0.2;
+	//real vx = 0.1;
 
 	//TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/DrivAer_Coarse.stl");
-	TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/DrivAer_NoSTLGroups.stl");
-	//TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/DrivAer_Fastback_Coarse_200k.stl");
-	//TriangularMesh* triangularMesh = TriangularMesh::make("M:/TestGridGeneration/STL/DrivAer_NoSTLGroups.stl");
-	//TriangularMesh* triangularMesh = TriangularMesh::make("M:/TestGridGeneration/STL/DrivAer_Coarse.stl");
-	gridBuilder->addCoarseGrid(-5, -5, -0.4, 15, 5, 5, dx);  // DrivAer
-    //gridBuilder->addGrid(new Cuboid(-1.5, -1.2, -1.5, 6.5, 1.5, 1.5), 2);
-    //gridBuilder->addGrid(triangularMesh, 3);                 // DrivAer
+	////TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/DrivAer_NoSTLGroups.stl");
+	////TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/DrivAer_Fastback_Coarse_200k.stl");
+	////TriangularMesh* triangularMesh = TriangularMesh::make("M:/TestGridGeneration/STL/DrivAer_NoSTLGroups.stl");
+	////TriangularMesh* triangularMesh = TriangularMesh::make("M:/TestGridGeneration/STL/DrivAer_Coarse.stl");
+	//gridBuilder->addCoarseGrid(-5, -5, -0.4, 15, 5, 5, dx);  // DrivAer
+ //   //gridBuilder->addGrid(new Cuboid(-1.5, -1.2, -1.5, 6.5, 1.5, 1.5), 2);
+ //   //gridBuilder->addGrid(triangularMesh, 3);                 // DrivAer
 
-    Object* floorBox = new Cuboid( -0.3, -1, -1, 4.0, 1, 0.2 );
-    Object* wakeBox = new Cuboid( 3.5, -1, -1, 5.5, 1, 0.8 );
+ //   Object* floorBox = new Cuboid( -0.3, -1, -1, 4.0, 1, 0.2 );
+ //   Object* wakeBox = new Cuboid( 3.5, -1, -1, 5.5, 1, 0.8 );
 
-    Conglomerate* refRegion = new Conglomerate();
+ //   Conglomerate* refRegion = new Conglomerate();
 
-    refRegion->add(floorBox);
-    refRegion->add(wakeBox);
-    refRegion->add(triangularMesh);
+ //   refRegion->add(floorBox);
+ //   refRegion->add(wakeBox);
+ //   refRegion->add(triangularMesh);
 
-    gridBuilder->setNumberOfLayers(15,8);
-    gridBuilder->addGrid(refRegion, 2);
-    
-    gridBuilder->setNumberOfLayers(10,8);
-    gridBuilder->addGrid(triangularMesh, 3);
+ //   gridBuilder->setNumberOfLayers(15,8);
+ //   gridBuilder->addGrid(refRegion, 2);
+ //   
+ //   gridBuilder->setNumberOfLayers(10,8);
+ //   gridBuilder->addGrid(triangularMesh, 3);
 
-	gridBuilder->addGeometry(triangularMesh);
+	//gridBuilder->addGeometry(triangularMesh);
     
     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // DLC
@@ -339,7 +339,7 @@ void multipleLevel(const std::string& configPath)
     // Wall Mounted Cube
     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-    //real dx = 0.2;
+ //   real dx = 0.2;
 	//real vx = 0.02;
 
 	//TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/Box_2.00.stl");
@@ -351,16 +351,17 @@ void multipleLevel(const std::string& configPath)
     // Testing layer refinement
     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-    //real dx = 0.2;
-    //real vx = 0.002;
+    real dx = 0.25;
+    real vx = 0.002;
 
-    //TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/Box_2.00.stl");
+    TriangularMesh* triangularMesh = TriangularMesh::make("C:/Users/lenz/Desktop/Work/gridGenerator/stl/Box_2.00.stl");
 
-    //gridBuilder->setNumberOfLayers(1, 8);   // this must come before the grids are added!!!
+    gridBuilder->addCoarseGrid(-4, -1.5, -1.5,
+                                4,  1.5,  1.5, dx);
 
-    //gridBuilder->addCoarseGrid(-4, -4, -4, 4, 4, 4, dx);
+    gridBuilder->setNumberOfLayers(3, 8);   // this must come before the grids are added!!!
     
-    //gridBuilder->addGrid(triangularMesh, 3);
+    gridBuilder->addGrid(triangularMesh, 1);
 
 
     //gridBuilder->addGrid( new Sphere( 0, 0, 0, 0.0005 ), 12 );
@@ -597,8 +598,9 @@ void multipleLevel(const std::string& configPath)
 	//}
 
     //SimulationFileWriter::write("D:/GRIDGENERATION/files/", gridBuilder, FILEFORMAT::ASCII);
+    SimulationFileWriter::write("C:/Users/lenz/Desktop/Work/gridGenerator/grid/", gridBuilder, FILEFORMAT::ASCII);
 
-    //return;
+    return;
 
     SPtr<Parameter> para = Parameter::make();
     SPtr<GridProvider> gridGenerator = GridGenerator::make(gridBuilder, para);
-- 
GitLab