diff --git a/.gitignore b/.gitignore
index d0a459bb12205d23608e5afd55251598e6a603ab..42243fd2b88c3bc620255b8f599bf74ae4f8b04c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@ __pycache__/
 .devcontainer/
 .sync/
 .idea/
+.cache/
 
 # Simulation input
 stl/
diff --git a/apps/gpu/DiluteGravityCurrents_Case1/DiluteGravityCurrents_Case1.cpp b/apps/gpu/DiluteGravityCurrents_Case1/DiluteGravityCurrents_Case1.cpp
index 838b2ccd5de9d89626ea8c61bf92592743a7ccba..560f525137b325bd2fe2259db7cb197759205955 100644
--- a/apps/gpu/DiluteGravityCurrents_Case1/DiluteGravityCurrents_Case1.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case1/DiluteGravityCurrents_Case1.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -99,8 +100,10 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
-
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -199,6 +202,7 @@ int main(int argc, char *argv[])
 
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -214,7 +218,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case2/DiluteGravityCurrents_Case2.cpp b/apps/gpu/DiluteGravityCurrents_Case2/DiluteGravityCurrents_Case2.cpp
index dcbb47c4b811434f10c6546e2c7b8ad2f829e6ae..4eed8b76452b943988cef60998839aa9c800a2f7 100644
--- a/apps/gpu/DiluteGravityCurrents_Case2/DiluteGravityCurrents_Case2.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case2/DiluteGravityCurrents_Case2.cpp
@@ -64,6 +64,9 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
+
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -99,8 +102,10 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
-
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +124,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -197,6 +202,7 @@ int main(int argc, char *argv[])
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
 
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
             //////////////////////////////////////////////////////////////////////////
@@ -211,7 +217,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case3/DiluteGravityCurrents_Case3.cpp b/apps/gpu/DiluteGravityCurrents_Case3/DiluteGravityCurrents_Case3.cpp
index e77d5f6ebc497bb8bd77a65cac6c6219c85ab5cc..076a60079726ad559450e98e1276224dcc873565 100644
--- a/apps/gpu/DiluteGravityCurrents_Case3/DiluteGravityCurrents_Case3.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case3/DiluteGravityCurrents_Case3.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -100,7 +101,9 @@ int main(int argc, char *argv[])
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
 
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -199,6 +202,7 @@ int main(int argc, char *argv[])
 
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -214,7 +218,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case4/DiluteGravityCurrents_Case4.cpp b/apps/gpu/DiluteGravityCurrents_Case4/DiluteGravityCurrents_Case4.cpp
index 7427aa9b7887e3645819a692f952f0e8320a81a1..320bbb69882349ce413691a8aacde95d2abd1135 100644
--- a/apps/gpu/DiluteGravityCurrents_Case4/DiluteGravityCurrents_Case4.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case4/DiluteGravityCurrents_Case4.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -100,7 +101,9 @@ int main(int argc, char *argv[])
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
 
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -196,6 +199,7 @@ int main(int argc, char *argv[])
             gridBuilder->setNoSlipBoundaryCondition(SideType::MY);
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -211,7 +215,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case5/DiluteGravityCurrents_Case5.cpp b/apps/gpu/DiluteGravityCurrents_Case5/DiluteGravityCurrents_Case5.cpp
index 9df9da2872112537b905fafc3f7275dfd6cb0430..c52f59de843534d1fc65a2740eec292584a2e8b1 100644
--- a/apps/gpu/DiluteGravityCurrents_Case5/DiluteGravityCurrents_Case5.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case5/DiluteGravityCurrents_Case5.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -99,8 +100,10 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
-
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,7 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
 
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
@@ -199,6 +203,7 @@ int main(int argc, char *argv[])
 
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -214,7 +219,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case6/DiluteGravityCurrents_Case6.cpp b/apps/gpu/DiluteGravityCurrents_Case6/DiluteGravityCurrents_Case6.cpp
index f1c8aa5c20d7bf987d0282c6e03b66a1ce3f89e2..0e7d3c44c7ead365a3c8de17c32de96a72322ea7 100644
--- a/apps/gpu/DiluteGravityCurrents_Case6/DiluteGravityCurrents_Case6.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case6/DiluteGravityCurrents_Case6.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -100,8 +101,10 @@ int main(int argc, char *argv[])
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
 
-        auto gridBuilder = MultipleGridBuilder::makeShared();
-
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
+        
         //////////////////////////////////////////////////////////////////////////
         // create grid
         //////////////////////////////////////////////////////////////////////////
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -196,6 +199,7 @@ int main(int argc, char *argv[])
             gridBuilder->setNoSlipBoundaryCondition(SideType::MY);
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -211,7 +215,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case7/DiluteGravityCurrents_Case7.cpp b/apps/gpu/DiluteGravityCurrents_Case7/DiluteGravityCurrents_Case7.cpp
index d6d4684369c03c90c63c02ae85ddfc2d5d88da89..d6143357336fdaad8106aadca2fcbdfb8330182b 100644
--- a/apps/gpu/DiluteGravityCurrents_Case7/DiluteGravityCurrents_Case7.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case7/DiluteGravityCurrents_Case7.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -99,8 +100,10 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
-
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -199,6 +202,7 @@ int main(int argc, char *argv[])
 
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -214,7 +218,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/DiluteGravityCurrents_Case8/DiluteGravityCurrents_Case8.cpp b/apps/gpu/DiluteGravityCurrents_Case8/DiluteGravityCurrents_Case8.cpp
index 09459acd8ca78d37501c68ada334a98a6fc4a525..6903ec9decc68ab7d51532e39192a97f1d997e7d 100644
--- a/apps/gpu/DiluteGravityCurrents_Case8/DiluteGravityCurrents_Case8.cpp
+++ b/apps/gpu/DiluteGravityCurrents_Case8/DiluteGravityCurrents_Case8.cpp
@@ -64,6 +64,7 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -99,8 +100,10 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
-
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -119,8 +122,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             real DeltaT = (real)2.5 * (real)nx / velocityLB;
 
             const uint timeStepOut = (int)DeltaT;
@@ -196,6 +199,7 @@ int main(int argc, char *argv[])
             gridBuilder->setNoSlipBoundaryCondition(SideType::MY);
             gridBuilder->setNoSlipBoundaryCondition(SideType::PZ);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
 
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
@@ -211,7 +215,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         }
diff --git a/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp b/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp
index 10dfd23bafd08b4b31c153ebd44b527c12aaced6..03cbaf3e77279186a9e3941a8f8644ed5538d980 100644
--- a/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp
+++ b/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp
@@ -32,6 +32,7 @@
 //=======================================================================================
 #define _USE_MATH_DEFINES
 #include <exception>
+#include <filesystem>
 #include <fstream>
 #include <iostream>
 #include <math.h>
@@ -47,6 +48,7 @@
 #include "Core/Logger/Logger.h"
 #include "Core/VectorTypes.h"
 #include "PointerDefinitions.h"
+#include "config/ConfigurationFile.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -56,6 +58,7 @@
 #include "GridGenerator/grid/GridFactory.h"
 
 #include "GridGenerator/geometries/Sphere/Sphere.h"
+#include "GridGenerator/geometries/TriangularMesh/TriangularMesh.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -65,6 +68,8 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -74,17 +79,18 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // Simulation parameters
         //////////////////////////////////////////////////////////////////////////
-        std::string outputPath("./output/Sphere");
-        std::string simulationName("Sphere");
+
+        const bool useConfigFile = true;
 
         const real L = 1.0;
-        const real Re = 1000.0;
+        const real dSphere = 0.2;
+        const real Re = 1000.0; // related to the sphere's diameter
         const real velocity = 1.0;
         const real dt = (real)0.5e-3;
         const uint nx = 64;
 
-        const uint timeStepOut = 10;
-        const uint timeStepEnd = 100;
+        const uint timeStepOut = 10000;
+        const uint timeStepEnd = 100000;
 
         //////////////////////////////////////////////////////////////////////////
         // setup logger
@@ -95,45 +101,73 @@ int main(int argc, char *argv[])
         logging::Logger::timeStamp(logging::Logger::ENABLE);
         logging::Logger::enablePrintedRankNumbers(logging::Logger::ENABLE);
 
+        //////////////////////////////////////////////////////////////////////////
+        // setup simulation parameters (with or without config file)
+        //////////////////////////////////////////////////////////////////////////
+
+        SPtr<Parameter> para;
+        BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
+        vf::basics::ConfigurationFile config;
+        if (useConfigFile) {
+            //////////////////////////////////////////////////////////////////////////
+            // read simulation parameters from config file
+            //////////////////////////////////////////////////////////////////////////
+
+            // assuming that a config files is stored parallel to this file.
+            std::filesystem::path configPath = __FILE__;
+
+            // the config file's default name can be replaced by passing a command line argument
+            std::string configName("config.txt");
+            if (argc == 2) {
+                configName = argv[1];
+                std::cout << "Using configFile command line argument: " << configName << std::endl;
+            }
+
+            configPath.replace_filename(configName);
+            config.load(configPath.string());
+
+            para = std::make_shared<Parameter>(config);
+        } else {
+            para = std::make_shared<Parameter>();
+        }
+
         //////////////////////////////////////////////////////////////////////////
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
 
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
         //////////////////////////////////////////////////////////////////////////
 
         real dx = L / real(nx);
-
-        gridBuilder->addCoarseGrid(-1.0 * L, -1.0 * L, -1.0 * L, 1.0 * L, 1.0 * L, 1.0 * L, dx);
+        gridBuilder->addCoarseGrid(-1.0 * L, -0.8 * L, -0.8 * L,
+                                    6.0 * L,  0.8 * L,  0.8 * L, dx);
 
         // use primitive
-        Object *sphere = new Sphere(0.0, 0.0, 0.0, 0.2);
+        Object *sphere = new Sphere(0.0, 0.0, 0.0, dSphere / 2.0);
+
         // use stl
-        // Object* sphere = TriangularMesh::make("stl/sphere.stl");
-        gridBuilder->addGeometry(sphere);
+        // std::string stlPath = "stl/sphere02.stl";
+        // if (useConfigFile && config.contains("STLPath")) {
+        //     stlPath = config.getValue<std::string>("STLPath");
+        // }
+        // std::cout << "Reading stl from " << stlPath << "." << std::endl;
+        // Object *sphere = TriangularMesh::make(stlPath);
 
+        gridBuilder->addGeometry(sphere);
         gridBuilder->setPeriodicBoundaryCondition(false, false, false);
-
-        gridBuilder->buildGrids(LBM, false);
-
-        //////////////////////////////////////////////////////////////////////////
-        // setup simulation parameters
-        //////////////////////////////////////////////////////////////////////////
-
-        SPtr<Parameter> para = Parameter::make();
+        gridBuilder->buildGrids(LBM, false);  // buildGrids() has to be called before setting the BCs!!!!
 
         //////////////////////////////////////////////////////////////////////////
         // compute parameters in lattice units
         //////////////////////////////////////////////////////////////////////////
 
         const real velocityLB = velocity * dt / dx; // LB units
-
-        const real vxLB = velocityLB / sqrt(2.0); // LB units
-
-        const real viscosityLB = nx * velocityLB / Re; // LB units
+        const real viscosityLB =  (dSphere / dx) * velocityLB / Re; // LB units
 
         *logging::out << logging::Logger::INFO_HIGH << "velocity  [dx/dt] = " << velocityLB << " \n";
         *logging::out << logging::Logger::INFO_HIGH << "viscosity [dx^2/dt] = " << viscosityLB << "\n";
@@ -142,17 +176,13 @@ int main(int argc, char *argv[])
         // set parameters
         //////////////////////////////////////////////////////////////////////////
 
-        para->setOutputPath(outputPath);
-        para->setOutputPrefix(simulationName);
-
-        para->setPathAndFilename(para->getOutputPath() + "/" + para->getOutputPrefix());
-
         para->setPrintFiles(true);
 
         para->setVelocityLB(velocityLB);
         para->setViscosityLB(viscosityLB);
 
         para->setVelocityRatio(velocity / velocityLB);
+        para->setDensityRatio((real)1.0);
 
         para->setTimestepOut(timeStepOut);
         para->setTimestepEnd(timeStepEnd);
@@ -161,20 +191,26 @@ int main(int argc, char *argv[])
         // set boundary conditions
         //////////////////////////////////////////////////////////////////////////
 
-        gridBuilder->setVelocityBoundaryCondition(SideType::MX, vxLB, 0.0, 0.0);
-        gridBuilder->setVelocityBoundaryCondition(SideType::MY, 0.0, 0.0, 0.0);
-        gridBuilder->setVelocityBoundaryCondition(SideType::PY, vxLB, 0.0, 0.0);
-        gridBuilder->setVelocityBoundaryCondition(SideType::MZ, vxLB, 0.0, 0.0);
-        gridBuilder->setVelocityBoundaryCondition(SideType::PZ, vxLB, 0.0, 0.0);
+        gridBuilder->setVelocityBoundaryCondition(SideType::MX, velocityLB, 0.0, 0.0);
+
+        gridBuilder->setSlipBoundaryCondition(SideType::PY, 0.0, 0.0, 0.0);
+        gridBuilder->setSlipBoundaryCondition(SideType::MY, 0.0, 0.0, 0.0);
+        gridBuilder->setSlipBoundaryCondition(SideType::PZ, 0.0, 0.0, 0.0);
+        gridBuilder->setSlipBoundaryCondition(SideType::MZ, 0.0, 0.0, 0.0);
+
         gridBuilder->setVelocityBoundaryCondition(SideType::GEOMETRY, 0.0, 0.0, 0.0);
-        gridBuilder->setPressureBoundaryCondition(SideType::PX, 0.0); // set pressure BC after velocity BCs
+        gridBuilder->setPressureBoundaryCondition(SideType::PX, 0.0); // set pressure boundary condition last
 
+        bcFactory.setVelocityBoundaryCondition(BoundaryConditionFactory::VelocityBC::VelocityCompressible);
+        bcFactory.setSlipBoundaryCondition(BoundaryConditionFactory::SlipBC::SlipCompressible);
+        bcFactory.setPressureBoundaryCondition(BoundaryConditionFactory::PressureBC::PressureNonEquilibriumCompressible);
+        bcFactory.setGeometryBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipCompressible);
+        
         //////////////////////////////////////////////////////////////////////////
-        // set copy mesh to simulation
+        // setup to copy mesh to simulation
         //////////////////////////////////////////////////////////////////////////
 
         SPtr<CudaMemoryManager> cudaMemoryManager = CudaMemoryManager::make(para);
-
         SPtr<GridProvider> gridGenerator = GridProvider::makeGridGenerator(gridBuilder, para, cudaMemoryManager);
 
         //////////////////////////////////////////////////////////////////////////
@@ -182,8 +218,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         Simulation sim;
-        SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-        sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+        SPtr<FileWriter> fileWriter = std::make_shared<FileWriter>();
+        sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
         sim.run();
         sim.free();
 
diff --git a/apps/gpu/FlowAroundSphere/config.txt b/apps/gpu/FlowAroundSphere/config.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1bdafa478c3d0e26474416cdbca79d4b04333636
--- /dev/null
+++ b/apps/gpu/FlowAroundSphere/config.txt
@@ -0,0 +1,16 @@
+##################################################
+# informations for Writing
+##################################################
+OutputPath = output/Sphere/
+OutputPrefix = SphereOpenSource
+
+##################################################
+# simulation time
+##################################################
+# TimeEnd=100000
+# TimeOut=1000
+
+##################################################
+# input
+##################################################
+STLPath = apps/gpu/FlowAroundSphere/sphere02.stl
\ No newline at end of file
diff --git a/apps/gpu/FlowAroundSphere/sphere02.stl b/apps/gpu/FlowAroundSphere/sphere02.stl
new file mode 100644
index 0000000000000000000000000000000000000000..3ff142d1a343b2e1016b75e65dde821d7a1f8e5a
--- /dev/null
+++ b/apps/gpu/FlowAroundSphere/sphere02.stl
@@ -0,0 +1,3138 @@
+solid Visualization Toolkit generated SLA File
+ facet normal 0.10450589731384756 0.020787518098262223 0.9943069930951618
+  outer loop
+   vertex 0.020791169255971909 0 0.097814761102199554
+   vertex 0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.088595824750780858 0.059197831240794162 0.99430699314302085
+  outer loop
+   vertex 0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex 0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.059197831240794162 0.088595824750780858 0.99430699314302085
+  outer loop
+   vertex 0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex 0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.020787518098262226 0.10450589731384755 0.9943069930951618
+  outer loop
+   vertex 0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex 1.2730919672892854e-18 0.020791169255971909 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.020787518098262219 0.10450589731384756 0.9943069930951618
+  outer loop
+   vertex 1.2730919672892854e-18 0.020791169255971909 0.097814761102199554
+   vertex -0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.059197831240794162 0.088595824750780858 0.99430699314302085
+  outer loop
+   vertex -0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex -0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.088595824750780858 0.059197831240794162 0.99430699314302085
+  outer loop
+   vertex -0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex -0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.10450589731384755 0.020787518098262226 0.9943069930951618
+  outer loop
+   vertex -0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex -0.020791169255971909 2.5461839345785708e-18 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.10450589731384756 -0.020787518098262219 0.9943069930951618
+  outer loop
+   vertex -0.020791169255971909 2.5461839345785708e-18 0.097814761102199554
+   vertex -0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.088595824750780858 -0.059197831240794162 0.99430699314302085
+  outer loop
+   vertex -0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex -0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.059197831240794162 -0.088595824750780858 0.99430699314302085
+  outer loop
+   vertex -0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex -0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal -0.020787518098262233 -0.10450589731384756 0.9943069930951618
+  outer loop
+   vertex -0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex -3.819275695072703e-18 -0.020791169255971909 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.020787518098262216 -0.10450589731384756 0.9943069930951618
+  outer loop
+   vertex -3.819275695072703e-18 -0.020791169255971909 0.097814761102199554
+   vertex 0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.059197831240794162 -0.088595824750780858 0.99430699314302085
+  outer loop
+   vertex 0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex 0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.088595824750780858 -0.059197831240794162 0.99430699314302085
+  outer loop
+   vertex 0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex 0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.10450589731384756 -0.020787518098262223 0.9943069930951618
+  outer loop
+   vertex 0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex 0.020791169255971909 0 0.097814761102199554
+   vertex 0 0 0.10000000149011612
+  endloop
+ endfacet
+ facet normal 0.10450589731384756 0.020787518098262223 -0.9943069930951618
+  outer loop
+   vertex 0.020791169255971909 0 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.088595824750780858 0.059197831240794162 -0.99430699314302085
+  outer loop
+   vertex 0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.01470157690346241 0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.059197831240794162 0.088595824750780858 -0.99430699314302085
+  outer loop
+   vertex 0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.020787518098262226 0.10450589731384755 -0.9943069930951618
+  outer loop
+   vertex 0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 1.2730919672892854e-18 0.020791169255971909 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.020787518098262219 0.10450589731384756 -0.9943069930951618
+  outer loop
+   vertex 1.2730919672892854e-18 0.020791169255971909 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.059197831240794162 0.088595824750780858 -0.99430699314302085
+  outer loop
+   vertex -0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.01470157690346241 0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.088595824750780858 0.059197831240794162 -0.99430699314302085
+  outer loop
+   vertex -0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.10450589731384755 0.02078751809826223 -0.9943069930951618
+  outer loop
+   vertex -0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.020791169255971909 2.5461839345785708e-18 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.10450589731384756 -0.020787518098262216 -0.9943069930951618
+  outer loop
+   vertex -0.020791169255971909 2.5461839345785708e-18 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.088595824750780858 -0.059197831240794162 -0.99430699314302085
+  outer loop
+   vertex -0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.059197831240794162 -0.088595824750780858 -0.99430699314302085
+  outer loop
+   vertex -0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.020787518098262233 -0.10450589731384756 -0.9943069930951618
+  outer loop
+   vertex -0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex -3.819275695072703e-18 -0.020791169255971909 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.020787518098262212 -0.10450589731384755 -0.9943069930951618
+  outer loop
+   vertex -3.819275695072703e-18 -0.020791169255971909 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.059197831240794162 -0.088595824750780858 -0.99430699314302085
+  outer loop
+   vertex 0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.088595824750780858 -0.059197831240794162 -0.99430699314302085
+  outer loop
+   vertex 0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.10450589731384756 -0.020787518098262223 -0.9943069930951618
+  outer loop
+   vertex 0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex 0 0 -0.10000000149011612
+   vertex 0.020791169255971909 0 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.30843476522401231 0.061351521400747594 0.94926497166124379
+  outer loop
+   vertex 0.020791169255971909 0 0.097814761102199554
+   vertex 0.040673665702342987 0 0.091354548931121826
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.30843478276930947 0.061351500668862545 0.94926496730034626
+  outer loop
+   vertex 0.020791169255971909 0 0.097814761102199554
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex 0.019208535552024841 0.0079564359039068222 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.49754554609711599 0.098967962699230083 0.86177361987826373
+  outer loop
+   vertex 0.040673665702342987 0 0.091354548931121826
+   vertex 0.058778524398803711 0 0.080901697278022766
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.49754549605911413 0.098968004229828863 0.86177364399826861
+  outer loop
+   vertex 0.040673665702342987 0 0.091354548931121826
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.6632812473204962 0.13193484346784404 0.7366486163918875
+  outer loop
+   vertex 0.058778524398803711 0 0.080901697278022766
+   vertex 0.074314482510089874 0 0.06691306084394455
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.66328124731730775 0.13193484347015969 0.73664861639434354
+  outer loop
+   vertex 0.058778524398803711 0 0.080901697278022766
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.79874089113149127 0.15887934482690994 0.58031917306068981
+  outer loop
+   vertex 0.074314482510089874 0 0.06691306084394455
+   vertex 0.086602538824081421 0 0.05000000074505806
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.79874079057134661 0.15887942196636892 0.58031929035065921
+  outer loop
+   vertex 0.074314482510089874 0 0.06691306084394455
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.89882617438269374 0.17878756470117699 0.40018310178316374
+  outer loop
+   vertex 0.086602538824081421 0 0.05000000074505806
+   vertex 0.095105648040771484 0 0.030901700258255005
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.89882620092364052 0.17878753861432078 0.40018305382588132
+  outer loop
+   vertex 0.086602538824081421 0 0.05000000074505806
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.96014288401665793 0.19098433051579031 0.20408485433664575
+  outer loop
+   vertex 0.095105648040771484 0 0.030901700258255005
+   vertex 0.099452190101146698 0 0.010452846065163612
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.96014294936226929 0.19098422428494741 0.20408464632156809
+  outer loop
+   vertex 0.095105648040771484 0 0.030901700258255005
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.98078527328214282 0.19509035781625048 -0
+  outer loop
+   vertex 0.099452190101146698 0 0.010452846065163612
+   vertex 0.099452190101146698 0 -0.010452846065163612
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.98078527328214282 0.19509035781625048 -0
+  outer loop
+   vertex 0.099452190101146698 0 0.010452846065163612
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.96014290587992079 0.19098421563577428 -0.20408485898382991
+  outer loop
+   vertex 0.099452190101146698 0 -0.010452846065163612
+   vertex 0.095105648040771484 0 -0.030901700258255005
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.96014292559861558 0.1909843387869575 -0.2040846509687585
+  outer loop
+   vertex 0.099452190101146698 0 -0.010452846065163612
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.89882617942320453 0.17878753433762079 -0.40018310402734325
+  outer loop
+   vertex 0.095105648040771484 0 -0.030901700258255005
+   vertex 0.086602538824081421 0 -0.05000000074505806
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.89882619396083974 0.17878756859551068 -0.40018305607006494
+  outer loop
+   vertex 0.095105648040771484 0 -0.030901700258255005
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.79874087880382028 0.15887943951689917 -0.58031916410411333
+  outer loop
+   vertex 0.086602538824081421 0 -0.05000000074505806
+   vertex 0.074314482510089874 0 -0.06691306084394455
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.7987408154183383 0.1588793297666366 -0.58031928139408939
+  outer loop
+   vertex 0.086602538824081421 0 -0.05000000074505806
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.66328124732023808 0.13193484347074255 -0.73664861639160084
+  outer loop
+   vertex 0.074314482510089874 0 -0.06691306084394455
+   vertex 0.058778524398803711 0 -0.080901697278022766
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.66328124731817861 0.13193484346738305 -0.73664861639405699
+  outer loop
+   vertex 0.074314482510089874 0 -0.06691306084394455
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.49754554356199898 0.098968013678745081 -0.86177361548731513
+  outer loop
+   vertex 0.058778524398803711 0 -0.080901697278022766
+   vertex 0.040673665702342987 0 -0.091354548931121826
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.49754551322598684 0.098967956160755946 -0.86177363960732289
+  outer loop
+   vertex 0.058778524398803711 0 -0.080901697278022766
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.30843476568236111 0.061351497270056753 -0.94926497307189694
+  outer loop
+   vertex 0.040673665702342987 0 -0.091354548931121826
+   vertex 0.020791169255971909 0 -0.097814761102199554
+   vertex 0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.3084347739583525 0.061351523138116801 -0.94926496871099864
+  outer loop
+   vertex 0.040673665702342987 0 -0.091354548931121826
+   vertex 0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.26147837970812587 0.17471428421919066 0.9492649660842799
+  outer loop
+   vertex 0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.26147840938106925 0.17471426893077599 0.9492649607246284
+  outer loop
+   vertex 0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex 0.01470157690346241 0.01470157690346241 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.42179874557711361 0.28183684066621417 0.86177364398829248
+  outer loop
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.42179864590164712 0.28183687150574754 0.86177368268901633
+  outer loop
+   vertex 0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.56230267786378618 0.37571865044532143 0.73664862327622749
+  outer loop
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.56230279592432497 0.37571862212216495 0.73664854760347465
+  outer loop
+   vertex 0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.67713972638750908 0.45245040321610314 0.5803192428116053
+  outer loop
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.67713981980897864 0.4524503781983546 0.58031915330896144
+  outer loop
+   vertex 0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.76198801003014671 0.50914415869095786 0.40018308090319588
+  outer loop
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.76198794657394719 0.50914418433618069 0.40018316910218049
+  outer loop
+   vertex 0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.81396988974665174 0.54387724854201425 0.20408468120903095
+  outer loop
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.81396982149820041 0.54387729795136042 0.20408482173673517
+  outer loop
+   vertex 0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.83146963292153175 0.55557020216110709 -0
+  outer loop
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.83146963292153175 0.55557020216110709 -0
+  outer loop
+   vertex 0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.81396984640124925 0.54387731459104727 -0.20408467806956454
+  outer loop
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.81396986593198373 0.54387723262956311 -0.20408481859726049
+  outer loop
+   vertex 0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.76198798009585644 0.50914420673480953 -0.40018307677589038
+  outer loop
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.76198797950532793 0.509144138294924 -0.40018316497487411
+  outer loop
+   vertex 0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.67713976273003673 0.45245034005942358 -0.58031924964628023
+  outer loop
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.67713977536749692 0.45245043594349216 -0.58031916014362273
+  outer loop
+   vertex 0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.56230271938745569 0.37571857098187661 -0.7366486321095076
+  outer loop
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.56230273840009004 0.37571869089438792 -0.73664855643676341
+  outer loop
+   vertex 0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.42179871051676798 0.28183691468019506 -0.86177363694298537
+  outer loop
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.42179870086462851 0.28183681079029427 -0.86177367564370844
+  outer loop
+   vertex 0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.26147839157789088 0.17471425703507376 -0.94926496781800662
+  outer loop
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex 0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex 0.01470157690346241 0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.26147838880858149 0.17471429029992128 -0.94926496245835557
+  outer loop
+   vertex 0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex 0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.17471429029992128 0.26147838880858149 0.94926496245835557
+  outer loop
+   vertex 0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.17471425703507376 0.26147839157789088 0.94926496781800662
+  outer loop
+   vertex 0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex 0.0079564359039068222 0.019208535552024841 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.28183681079029427 0.42179870086462851 0.86177367564370844
+  outer loop
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.28183691468019506 0.42179871051676798 0.86177363694298537
+  outer loop
+   vertex 0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.37571869089438792 0.56230273840009004 0.73664855643676341
+  outer loop
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.37571857098187661 0.56230271938745569 0.7366486321095076
+  outer loop
+   vertex 0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.45245043594349216 0.67713977536749692 0.58031916014362273
+  outer loop
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.45245034005942358 0.67713976273003673 0.58031924964628023
+  outer loop
+   vertex 0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.509144138294924 0.76198797950532793 0.40018316497487411
+  outer loop
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.50914420673480953 0.76198798009585644 0.40018307677589038
+  outer loop
+   vertex 0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.54387723262956311 0.81396986593198373 0.20408481859726049
+  outer loop
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.54387731459104727 0.81396984640124925 0.20408467806956454
+  outer loop
+   vertex 0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.55557020216110709 0.83146963292153175 -0
+  outer loop
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.55557020216110709 0.83146963292153175 -0
+  outer loop
+   vertex 0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.54387729795136042 0.81396982149820041 -0.20408482173673517
+  outer loop
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.54387724854201425 0.81396988974665174 -0.20408468120903095
+  outer loop
+   vertex 0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.50914418433618069 0.76198794657394719 -0.40018316910218049
+  outer loop
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.50914415869095786 0.76198801003014671 -0.40018308090319588
+  outer loop
+   vertex 0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.4524503781983546 0.67713981980897864 -0.58031915330896144
+  outer loop
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.45245040321610314 0.67713972638750908 -0.5803192428116053
+  outer loop
+   vertex 0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.37571862212216495 0.56230279592432497 -0.73664854760347465
+  outer loop
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.37571865044532143 0.56230267786378618 -0.73664862327622749
+  outer loop
+   vertex 0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.28183687150574754 0.42179864590164712 -0.86177368268901633
+  outer loop
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.28183684066621417 0.42179874557711361 -0.86177364398829248
+  outer loop
+   vertex 0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.17471426893077599 0.26147840938106925 -0.9492649607246284
+  outer loop
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex 0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex 0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.17471428421919066 0.26147837970812587 -0.9492649660842799
+  outer loop
+   vertex 0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex 0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.061351523138116808 0.3084347739583525 0.94926496871099864
+  outer loop
+   vertex 0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.061351497270056753 0.30843476568236106 0.94926497307189694
+  outer loop
+   vertex 0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+   vertex 1.2730919672892854e-18 0.020791169255971909 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.09896795616075596 0.49754551322598684 0.86177363960732289
+  outer loop
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.098968013678745095 0.49754554356199898 0.86177361548731501
+  outer loop
+   vertex 0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.13193484346738305 0.6632812473181785 0.73664861639405688
+  outer loop
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.13193484347074255 0.66328124732023797 0.73664861639160084
+  outer loop
+   vertex 0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.15887932976663663 0.79874081541833841 0.5803192813940895
+  outer loop
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.15887943951689923 0.79874087880382039 0.58031916410411333
+  outer loop
+   vertex 0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.17878756859551068 0.89882619396083951 0.40018305607006488
+  outer loop
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.17878753433762079 0.89882617942320442 0.40018310402734319
+  outer loop
+   vertex 0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.19098433878695753 0.96014292559861558 0.2040846509687585
+  outer loop
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19098421563577431 0.96014290587992079 0.20408485898382991
+  outer loop
+   vertex 0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.19509035781625048 0.98078527328214271 -0
+  outer loop
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19509035781625048 0.98078527328214271 -0
+  outer loop
+   vertex 0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19098422428494746 0.9601429493622694 -0.20408464632156811
+  outer loop
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.19098433051579031 0.96014288401665793 -0.20408485433664572
+  outer loop
+   vertex 0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.17878753861432081 0.89882620092364052 -0.40018305382588126
+  outer loop
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.17878756470117702 0.89882617438269363 -0.40018310178316374
+  outer loop
+   vertex 0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.15887942196636895 0.79874079057134661 -0.58031929035065921
+  outer loop
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.15887934482690999 0.79874089113149138 -0.58031917306068981
+  outer loop
+   vertex 0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.13193484347015971 0.66328124731730786 -0.73664861639434365
+  outer loop
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.13193484346784407 0.6632812473204962 -0.73664861639188761
+  outer loop
+   vertex 0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.098968004229828876 0.49754549605911413 -0.86177364399826861
+  outer loop
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.098967962699230097 0.49754554609711604 -0.86177361987826384
+  outer loop
+   vertex 0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.061351500668862552 0.30843478276930947 -0.94926496730034626
+  outer loop
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex 0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex 1.2730919672892854e-18 0.020791169255971909 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.061351521400747608 0.30843476522401225 -0.94926497166124379
+  outer loop
+   vertex 0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex 1.2730919672892854e-18 0.020791169255971909 -0.097814761102199554
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.061351521400747587 0.30843476522401225 0.94926497166124379
+  outer loop
+   vertex 1.2730919672892854e-18 0.020791169255971909 0.097814761102199554
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.061351500668862524 0.30843478276930947 0.94926496730034626
+  outer loop
+   vertex 1.2730919672892854e-18 0.020791169255971909 0.097814761102199554
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex -0.0079564359039068222 0.019208535552024841 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.098967962699230083 0.49754554609711604 0.86177361987826384
+  outer loop
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.098968004229828835 0.49754549605911413 0.86177364399826861
+  outer loop
+   vertex 2.4905436306751913e-18 0.040673665702342987 0.091354548931121826
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.13193484346784401 0.66328124732049609 0.7366486163918875
+  outer loop
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.13193484347015969 0.66328124731730786 0.73664861639434365
+  outer loop
+   vertex 3.5991468040503975e-18 0.058778524398803711 0.080901697278022766
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.15887934482690991 0.79874089113149138 0.58031917306068992
+  outer loop
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.15887942196636889 0.79874079057134661 0.58031929035065921
+  outer loop
+   vertex 4.5504495898297635e-18 0.074314482510089874 0.06691306084394455
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.17878756470117696 0.89882617438269374 0.4001831017831638
+  outer loop
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.17878753861432076 0.89882620092364052 0.40018305382588132
+  outer loop
+   vertex 5.302876236065149e-18 0.086602538824081421 0.05000000074505806
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.19098433051579028 0.96014288401665793 0.20408485433664575
+  outer loop
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19098422428494741 0.9601429493622694 0.20408464632156811
+  outer loop
+   vertex 5.823541763914202e-18 0.095105648040771484 0.030901700258255005
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.19509035781625042 0.98078527328214271 0
+  outer loop
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19509035781625042 0.98078527328214271 0
+  outer loop
+   vertex 6.0896904347255889e-18 0.099452190101146698 0.010452846065163612
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19098421563577425 0.96014290587992079 -0.20408485898382991
+  outer loop
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.19098433878695747 0.96014292559861558 -0.20408465096875852
+  outer loop
+   vertex 6.0896904347255889e-18 0.099452190101146698 -0.010452846065163612
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.17878753433762073 0.89882617942320442 -0.40018310402734325
+  outer loop
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.17878756859551062 0.89882619396083963 -0.40018305607006494
+  outer loop
+   vertex 5.823541763914202e-18 0.095105648040771484 -0.030901700258255005
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.15887943951689915 0.79874087880382016 -0.58031916410411333
+  outer loop
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.15887932976663657 0.7987408154183383 -0.58031928139408939
+  outer loop
+   vertex 5.302876236065149e-18 0.086602538824081421 -0.05000000074505806
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.13193484347074252 0.66328124732023797 -0.73664861639160084
+  outer loop
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.13193484346738302 0.66328124731817861 -0.73664861639405699
+  outer loop
+   vertex 4.5504495898297635e-18 0.074314482510089874 -0.06691306084394455
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.098968013678745068 0.49754554356199898 -0.86177361548731513
+  outer loop
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.098967956160755932 0.49754551322598684 -0.86177363960732289
+  outer loop
+   vertex 3.5991468040503975e-18 0.058778524398803711 -0.080901697278022766
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.061351497270056739 0.30843476568236111 -0.94926497307189694
+  outer loop
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+   vertex 1.2730919672892854e-18 0.020791169255971909 -0.097814761102199554
+   vertex -0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.061351523138116801 0.30843477395835256 -0.94926496871099864
+  outer loop
+   vertex 2.4905436306751913e-18 0.040673665702342987 -0.091354548931121826
+   vertex -0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.17471428421919066 0.26147837970812587 0.9492649660842799
+  outer loop
+   vertex -0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.17471426893077599 0.26147840938106925 0.9492649607246284
+  outer loop
+   vertex -0.0079564359039068222 0.019208535552024841 0.097814761102199554
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex -0.01470157690346241 0.01470157690346241 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.28183684066621417 0.42179874557711361 0.86177364398829248
+  outer loop
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.28183687150574754 0.42179864590164712 0.86177368268901633
+  outer loop
+   vertex -0.015565137378871441 0.037577565759420395 0.091354548931121826
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.37571865044532143 0.56230267786378618 0.73664862327622749
+  outer loop
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.37571862212216495 0.56230279592432497 0.73664854760347465
+  outer loop
+   vertex -0.022493567317724228 0.054304275661706924 0.080901697278022766
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.45245040321610314 0.67713972638750908 0.5803192428116053
+  outer loop
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.4524503781983546 0.67713981980897864 0.58031915330896144
+  outer loop
+   vertex -0.028438922017812729 0.068657629191875458 0.06691306084394455
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.50914415869095786 0.76198801003014671 0.40018308090319588
+  outer loop
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.50914418433618069 0.76198794657394719 0.40018316910218049
+  outer loop
+   vertex -0.033141355961561203 0.080010317265987396 0.05000000074505806
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.54387724854201425 0.81396988974665174 0.20408468120903095
+  outer loop
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.54387729795136042 0.81396982149820041 0.20408482173673517
+  outer loop
+   vertex -0.036395356059074402 0.087866164743900299 0.030901700258255005
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.55557020216110709 0.83146963292153175 0
+  outer loop
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.55557020216110709 0.83146963292153175 0
+  outer loop
+   vertex -0.038058705627918243 0.091881841421127319 0.010452846065163612
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.54387731459104727 0.81396984640124925 -0.20408467806956454
+  outer loop
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.54387723262956311 0.81396986593198373 -0.20408481859726049
+  outer loop
+   vertex -0.038058705627918243 0.091881841421127319 -0.010452846065163612
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.50914420673480953 0.76198798009585644 -0.40018307677589038
+  outer loop
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.509144138294924 0.76198797950532793 -0.40018316497487411
+  outer loop
+   vertex -0.036395356059074402 0.087866164743900299 -0.030901700258255005
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.45245034005942358 0.67713976273003673 -0.58031924964628023
+  outer loop
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.45245043594349216 0.67713977536749692 -0.58031916014362273
+  outer loop
+   vertex -0.033141355961561203 0.080010317265987396 -0.05000000074505806
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.37571857098187661 0.56230271938745569 -0.7366486321095076
+  outer loop
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.37571869089438792 0.56230273840009004 -0.73664855643676341
+  outer loop
+   vertex -0.028438922017812729 0.068657629191875458 -0.06691306084394455
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.28183691468019506 0.42179871051676798 -0.86177363694298537
+  outer loop
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.28183681079029427 0.42179870086462851 -0.86177367564370844
+  outer loop
+   vertex -0.022493567317724228 0.054304275661706924 -0.080901697278022766
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.17471425703507376 0.26147839157789088 -0.94926496781800662
+  outer loop
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex -0.0079564359039068222 0.019208535552024841 -0.097814761102199554
+   vertex -0.01470157690346241 0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.17471429029992128 0.26147838880858149 -0.94926496245835557
+  outer loop
+   vertex -0.015565137378871441 0.037577565759420395 -0.091354548931121826
+   vertex -0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.26147838880858149 0.17471429029992128 0.94926496245835557
+  outer loop
+   vertex -0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.26147839157789088 0.17471425703507376 0.94926496781800662
+  outer loop
+   vertex -0.01470157690346241 0.01470157690346241 0.097814761102199554
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex -0.019208535552024841 0.0079564359039068222 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.42179870086462851 0.28183681079029427 0.86177367564370844
+  outer loop
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.42179871051676798 0.28183691468019506 0.86177363694298537
+  outer loop
+   vertex -0.028760623186826706 0.028760623186826706 0.091354548931121826
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.56230273840009004 0.37571869089438792 0.73664855643676341
+  outer loop
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.56230271938745569 0.37571857098187661 0.7366486321095076
+  outer loop
+   vertex -0.041562695056200027 0.041562695056200027 0.080901697278022766
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.67713977536749692 0.45245043594349216 0.58031916014362273
+  outer loop
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.67713976273003673 0.45245034005942358 0.58031924964628023
+  outer loop
+   vertex -0.052548274397850037 0.052548274397850037 0.06691306084394455
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.76198797950532793 0.509144138294924 0.40018316497487411
+  outer loop
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.76198798009585644 0.50914420673480953 0.40018307677589038
+  outer loop
+   vertex -0.061237242072820663 0.061237242072820663 0.05000000074505806
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.81396986593198373 0.54387723262956311 0.20408481859726049
+  outer loop
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.81396984640124925 0.54387731459104727 0.20408467806956454
+  outer loop
+   vertex -0.067249849438667297 0.067249849438667297 0.030901700258255005
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.83146963292153175 0.55557020216110709 0
+  outer loop
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.83146963292153175 0.55557020216110709 0
+  outer loop
+   vertex -0.070323318243026733 0.070323318243026733 0.010452846065163612
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.81396982149820041 0.54387729795136042 -0.20408482173673517
+  outer loop
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.81396988974665174 0.54387724854201425 -0.20408468120903095
+  outer loop
+   vertex -0.070323318243026733 0.070323318243026733 -0.010452846065163612
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.76198794657394719 0.50914418433618069 -0.40018316910218049
+  outer loop
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.76198801003014671 0.50914415869095786 -0.40018308090319588
+  outer loop
+   vertex -0.067249849438667297 0.067249849438667297 -0.030901700258255005
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.67713981980897864 0.4524503781983546 -0.58031915330896144
+  outer loop
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.67713972638750908 0.45245040321610314 -0.5803192428116053
+  outer loop
+   vertex -0.061237242072820663 0.061237242072820663 -0.05000000074505806
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.56230279592432497 0.37571862212216495 -0.73664854760347465
+  outer loop
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.56230267786378618 0.37571865044532143 -0.73664862327622749
+  outer loop
+   vertex -0.052548274397850037 0.052548274397850037 -0.06691306084394455
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.42179864590164712 0.28183687150574754 -0.86177368268901633
+  outer loop
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.42179874557711361 0.28183684066621417 -0.86177364398829248
+  outer loop
+   vertex -0.041562695056200027 0.041562695056200027 -0.080901697278022766
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.26147840938106925 0.17471426893077599 -0.9492649607246284
+  outer loop
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex -0.01470157690346241 0.01470157690346241 -0.097814761102199554
+   vertex -0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.26147837970812587 0.17471428421919066 -0.9492649660842799
+  outer loop
+   vertex -0.028760623186826706 0.028760623186826706 -0.091354548931121826
+   vertex -0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.30843477395835256 0.061351523138116815 0.94926496871099864
+  outer loop
+   vertex -0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.30843476568236106 0.061351497270056773 0.94926497307189694
+  outer loop
+   vertex -0.019208535552024841 0.0079564359039068222 0.097814761102199554
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+   vertex -0.020791169255971909 2.5461839345785708e-18 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.49754551322598684 0.098967956160755974 0.86177363960732301
+  outer loop
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.49754554356199887 0.098968013678745095 0.86177361548731501
+  outer loop
+   vertex -0.037577565759420395 0.015565137378871441 0.091354548931121826
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.6632812473181785 0.13193484346738307 0.73664861639405688
+  outer loop
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.66328124732023797 0.13193484347074261 0.73664861639160095
+  outer loop
+   vertex -0.054304275661706924 0.022493567317724228 0.080901697278022766
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.79874081541833841 0.15887932976663666 0.58031928139408939
+  outer loop
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.79874087880382028 0.15887943951689923 0.58031916410411333
+  outer loop
+   vertex -0.068657629191875458 0.028438922017812729 0.06691306084394455
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.89882619396083963 0.1787875685955107 0.40018305607006494
+  outer loop
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.89882617942320453 0.17878753433762085 0.40018310402734325
+  outer loop
+   vertex -0.080010317265987396 0.033141355961561203 0.05000000074505806
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.96014292559861558 0.19098433878695759 0.20408465096875852
+  outer loop
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.96014290587992079 0.19098421563577436 0.20408485898382991
+  outer loop
+   vertex -0.087866164743900299 0.036395356059074402 0.030901700258255005
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.98078527328214271 0.19509035781625053 0
+  outer loop
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.98078527328214271 0.19509035781625053 0
+  outer loop
+   vertex -0.091881841421127319 0.038058705627918243 0.010452846065163612
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.9601429493622694 0.19098422428494752 -0.20408464632156814
+  outer loop
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.96014288401665793 0.19098433051579036 -0.20408485433664575
+  outer loop
+   vertex -0.091881841421127319 0.038058705627918243 -0.010452846065163612
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.89882620092364052 0.17878753861432084 -0.40018305382588126
+  outer loop
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.89882617438269374 0.17878756470117704 -0.4001831017831638
+  outer loop
+   vertex -0.087866164743900299 0.036395356059074402 -0.030901700258255005
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.79874079057134661 0.15887942196636898 -0.58031929035065921
+  outer loop
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.79874089113149138 0.15887934482690999 -0.58031917306068981
+  outer loop
+   vertex -0.080010317265987396 0.033141355961561203 -0.05000000074505806
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.66328124731730775 0.13193484347015974 -0.73664861639434365
+  outer loop
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.66328124732049609 0.13193484346784407 -0.7366486163918875
+  outer loop
+   vertex -0.068657629191875458 0.028438922017812729 -0.06691306084394455
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.49754549605911413 0.09896800422982889 -0.86177364399826861
+  outer loop
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.49754554609711604 0.098967962699230111 -0.86177361987826384
+  outer loop
+   vertex -0.054304275661706924 0.022493567317724228 -0.080901697278022766
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.30843478276930947 0.061351500668862552 -0.94926496730034626
+  outer loop
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex -0.019208535552024841 0.0079564359039068222 -0.097814761102199554
+   vertex -0.020791169255971909 2.5461839345785708e-18 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.30843476522401231 0.061351521400747615 -0.94926497166124379
+  outer loop
+   vertex -0.037577565759420395 0.015565137378871441 -0.091354548931121826
+   vertex -0.020791169255971909 2.5461839345785708e-18 -0.097814761102199554
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.30843476522401225 -0.061351521400747573 0.94926497166124379
+  outer loop
+   vertex -0.020791169255971909 2.5461839345785708e-18 0.097814761102199554
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.30843478276930947 -0.061351500668862524 0.94926496730034626
+  outer loop
+   vertex -0.020791169255971909 2.5461839345785708e-18 0.097814761102199554
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex -0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.49754554609711604 -0.098967962699230055 0.86177361987826384
+  outer loop
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.49754549605911413 -0.098968004229828835 0.86177364399826861
+  outer loop
+   vertex -0.040673665702342987 4.9810872613503827e-18 0.091354548931121826
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.6632812473204962 -0.13193484346784398 0.7366486163918875
+  outer loop
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.66328124731730786 -0.13193484347015966 0.73664861639434365
+  outer loop
+   vertex -0.058778524398803711 7.1982936081007951e-18 0.080901697278022766
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.79874089113149138 -0.15887934482690988 0.58031917306068992
+  outer loop
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.79874079057134661 -0.15887942196636889 0.58031929035065921
+  outer loop
+   vertex -0.074314482510089874 9.100899179659527e-18 0.06691306084394455
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.89882617438269374 -0.17878756470117693 0.4001831017831638
+  outer loop
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.89882620092364052 -0.17878753861432073 0.40018305382588132
+  outer loop
+   vertex -0.086602538824081421 1.0605752472130298e-17 0.05000000074505806
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.96014288401665793 -0.19098433051579022 0.20408485433664572
+  outer loop
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.9601429493622694 -0.19098422428494735 0.20408464632156811
+  outer loop
+   vertex -0.095105648040771484 1.1647083527828404e-17 0.030901700258255005
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.98078527328214282 -0.19509035781625039 0
+  outer loop
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.98078527328214282 -0.19509035781625039 0
+  outer loop
+   vertex -0.099452190101146698 1.2179380869451178e-17 0.010452846065163612
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.96014290587992079 -0.1909842156357742 -0.20408485898382989
+  outer loop
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.96014292559861558 -0.19098433878695742 -0.2040846509687585
+  outer loop
+   vertex -0.099452190101146698 1.2179380869451178e-17 -0.010452846065163612
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.89882617942320464 -0.17878753433762073 -0.40018310402734331
+  outer loop
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.89882619396083963 -0.17878756859551059 -0.40018305607006494
+  outer loop
+   vertex -0.095105648040771484 1.1647083527828404e-17 -0.030901700258255005
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.79874087880382028 -0.15887943951689912 -0.58031916410411333
+  outer loop
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.79874081541833841 -0.15887932976663655 -0.58031928139408928
+  outer loop
+   vertex -0.086602538824081421 1.0605752472130298e-17 -0.05000000074505806
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.66328124732023808 -0.1319348434707425 -0.73664861639160084
+  outer loop
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.6632812473181785 -0.13193484346738299 -0.73664861639405688
+  outer loop
+   vertex -0.074314482510089874 9.100899179659527e-18 -0.06691306084394455
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.49754554356199887 -0.098968013678745026 -0.86177361548731501
+  outer loop
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.49754551322598689 -0.098967956160755918 -0.86177363960732289
+  outer loop
+   vertex -0.058778524398803711 7.1982936081007951e-18 -0.080901697278022766
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.30843476568236111 -0.061351497270056739 -0.94926497307189694
+  outer loop
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+   vertex -0.020791169255971909 2.5461839345785708e-18 -0.097814761102199554
+   vertex -0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.3084347739583525 -0.06135152313811678 -0.94926496871099864
+  outer loop
+   vertex -0.040673665702342987 4.9810872613503827e-18 -0.091354548931121826
+   vertex -0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.26147837970812587 -0.17471428421919066 0.9492649660842799
+  outer loop
+   vertex -0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.26147840938106925 -0.17471426893077599 0.9492649607246284
+  outer loop
+   vertex -0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex -0.01470157690346241 -0.01470157690346241 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.42179874557711361 -0.28183684066621417 0.86177364398829248
+  outer loop
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.42179864590164712 -0.28183687150574754 0.86177368268901633
+  outer loop
+   vertex -0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.56230267786378618 -0.37571865044532143 0.73664862327622749
+  outer loop
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.56230279592432497 -0.37571862212216495 0.73664854760347465
+  outer loop
+   vertex -0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.67713972638750908 -0.45245040321610314 0.5803192428116053
+  outer loop
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.67713981980897864 -0.4524503781983546 0.58031915330896144
+  outer loop
+   vertex -0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.76198801003014671 -0.50914415869095786 0.40018308090319588
+  outer loop
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.76198794657394719 -0.50914418433618069 0.40018316910218049
+  outer loop
+   vertex -0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.81396988974665174 -0.54387724854201425 0.20408468120903095
+  outer loop
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.81396982149820041 -0.54387729795136042 0.20408482173673517
+  outer loop
+   vertex -0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.83146963292153175 -0.55557020216110709 0
+  outer loop
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.83146963292153175 -0.55557020216110709 0
+  outer loop
+   vertex -0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.81396984640124925 -0.54387731459104727 -0.20408467806956454
+  outer loop
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.81396986593198373 -0.54387723262956311 -0.20408481859726049
+  outer loop
+   vertex -0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.76198798009585644 -0.50914420673480953 -0.40018307677589038
+  outer loop
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.76198797950532793 -0.509144138294924 -0.40018316497487411
+  outer loop
+   vertex -0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.67713976273003673 -0.45245034005942358 -0.58031924964628023
+  outer loop
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.67713977536749692 -0.45245043594349216 -0.58031916014362273
+  outer loop
+   vertex -0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.56230271938745569 -0.37571857098187661 -0.7366486321095076
+  outer loop
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.56230273840009004 -0.37571869089438792 -0.73664855643676341
+  outer loop
+   vertex -0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.42179871051676798 -0.28183691468019506 -0.86177363694298537
+  outer loop
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.42179870086462851 -0.28183681079029427 -0.86177367564370844
+  outer loop
+   vertex -0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.26147839157789088 -0.17471425703507376 -0.94926496781800662
+  outer loop
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex -0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex -0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.26147838880858149 -0.17471429029992128 -0.94926496245835557
+  outer loop
+   vertex -0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex -0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.17471429029992128 -0.26147838880858149 0.94926496245835557
+  outer loop
+   vertex -0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.17471425703507376 -0.26147839157789088 0.94926496781800662
+  outer loop
+   vertex -0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex -0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.28183681079029427 -0.42179870086462851 0.86177367564370844
+  outer loop
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.28183691468019506 -0.42179871051676798 0.86177363694298537
+  outer loop
+   vertex -0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.37571869089438792 -0.56230273840009004 0.73664855643676341
+  outer loop
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.37571857098187661 -0.56230271938745569 0.7366486321095076
+  outer loop
+   vertex -0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.45245043594349216 -0.67713977536749692 0.58031916014362273
+  outer loop
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.45245034005942358 -0.67713976273003673 0.58031924964628023
+  outer loop
+   vertex -0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.509144138294924 -0.76198797950532793 0.40018316497487411
+  outer loop
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.50914420673480953 -0.76198798009585644 0.40018307677589038
+  outer loop
+   vertex -0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.54387723262956311 -0.81396986593198373 0.20408481859726049
+  outer loop
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.54387731459104727 -0.81396984640124925 0.20408467806956454
+  outer loop
+   vertex -0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.55557020216110709 -0.83146963292153175 0
+  outer loop
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.55557020216110709 -0.83146963292153175 0
+  outer loop
+   vertex -0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.54387729795136042 -0.81396982149820041 -0.20408482173673517
+  outer loop
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.54387724854201425 -0.81396988974665174 -0.20408468120903095
+  outer loop
+   vertex -0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.50914418433618069 -0.76198794657394719 -0.40018316910218049
+  outer loop
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.50914415869095786 -0.76198801003014671 -0.40018308090319588
+  outer loop
+   vertex -0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.4524503781983546 -0.67713981980897864 -0.58031915330896144
+  outer loop
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.45245040321610314 -0.67713972638750908 -0.5803192428116053
+  outer loop
+   vertex -0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.37571862212216495 -0.56230279592432497 -0.73664854760347465
+  outer loop
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.37571865044532143 -0.56230267786378618 -0.73664862327622749
+  outer loop
+   vertex -0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.28183687150574754 -0.42179864590164712 -0.86177368268901633
+  outer loop
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.28183684066621417 -0.42179874557711361 -0.86177364398829248
+  outer loop
+   vertex -0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.17471426893077599 -0.26147840938106925 -0.9492649607246284
+  outer loop
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex -0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex -0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.17471428421919066 -0.26147837970812587 -0.9492649660842799
+  outer loop
+   vertex -0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex -0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.061351523138116815 -0.3084347739583525 0.94926496871099864
+  outer loop
+   vertex -0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.061351497270056773 -0.308434765682361 0.94926497307189694
+  outer loop
+   vertex -0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+   vertex -3.819275695072703e-18 -0.020791169255971909 0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.098967956160755974 -0.49754551322598678 0.86177363960732289
+  outer loop
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.098968013678745109 -0.49754554356199887 0.86177361548731501
+  outer loop
+   vertex -0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.1319348434673831 -0.6632812473181785 0.73664861639405688
+  outer loop
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.13193484347074261 -0.66328124732023797 0.73664861639160084
+  outer loop
+   vertex -0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.15887932976663666 -0.79874081541833841 0.58031928139408939
+  outer loop
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.15887943951689926 -0.79874087880382028 0.58031916410411333
+  outer loop
+   vertex -0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.17878756859551073 -0.89882619396083951 0.40018305607006494
+  outer loop
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.1787875343376209 -0.89882617942320453 0.40018310402734331
+  outer loop
+   vertex -0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.19098433878695761 -0.96014292559861558 0.20408465096875852
+  outer loop
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19098421563577436 -0.96014290587992068 0.20408485898382989
+  outer loop
+   vertex -0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.19509035781625056 -0.98078527328214271 0
+  outer loop
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19509035781625056 -0.98078527328214271 0
+  outer loop
+   vertex -0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.19098422428494752 -0.9601429493622694 -0.20408464632156814
+  outer loop
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.19098433051579039 -0.96014288401665793 -0.20408485433664575
+  outer loop
+   vertex -0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal -0.17878753861432084 -0.89882620092364052 -0.40018305382588126
+  outer loop
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.17878756470117704 -0.89882617438269374 -0.4001831017831638
+  outer loop
+   vertex -0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal -0.15887942196636901 -0.79874079057134661 -0.58031929035065921
+  outer loop
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.15887934482690999 -0.79874089113149138 -0.58031917306068981
+  outer loop
+   vertex -0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal -0.13193484347015974 -0.66328124731730775 -0.73664861639434354
+  outer loop
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.13193484346784412 -0.66328124732049609 -0.73664861639188761
+  outer loop
+   vertex -0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal -0.098968004229828904 -0.49754549605911413 -0.86177364399826872
+  outer loop
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal -0.098967962699230125 -0.49754554609711599 -0.86177361987826384
+  outer loop
+   vertex -0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal -0.061351500668862566 -0.30843478276930947 -0.94926496730034626
+  outer loop
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex -0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex -3.819275695072703e-18 -0.020791169255971909 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal -0.061351521400747615 -0.3084347652240122 -0.94926497166124379
+  outer loop
+   vertex -0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex -3.819275695072703e-18 -0.020791169255971909 -0.097814761102199554
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.061351521400747566 -0.30843476522401225 0.94926497166124391
+  outer loop
+   vertex -3.819275695072703e-18 -0.020791169255971909 0.097814761102199554
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.06135150066886251 -0.30843478276930952 0.94926496730034615
+  outer loop
+   vertex -3.819275695072703e-18 -0.020791169255971909 0.097814761102199554
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex 0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.098967962699230042 -0.49754554609711604 0.86177361987826384
+  outer loop
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.098968004229828821 -0.49754549605911419 0.86177364399826872
+  outer loop
+   vertex -7.4716313056158803e-18 -0.040673665702342987 0.091354548931121826
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.13193484346784395 -0.6632812473204962 0.7366486163918875
+  outer loop
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.13193484347015963 -0.66328124731730786 0.73664861639434354
+  outer loop
+   vertex -1.0797439998560886e-17 -0.058778524398803711 0.080901697278022766
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.15887934482690988 -0.79874089113149138 0.58031917306068992
+  outer loop
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.15887942196636887 -0.79874079057134661 0.58031929035065932
+  outer loop
+   vertex -1.3651348769489291e-17 -0.074314482510089874 0.06691306084394455
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.17878756470117688 -0.89882617438269374 0.40018310178316374
+  outer loop
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.17878753861432073 -0.89882620092364052 0.40018305382588132
+  outer loop
+   vertex -1.5908628708195447e-17 -0.086602538824081421 0.05000000074505806
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.1909843305157902 -0.96014288401665793 0.20408485433664572
+  outer loop
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19098422428494732 -0.9601429493622694 0.20408464632156811
+  outer loop
+   vertex -1.7470625291742606e-17 -0.095105648040771484 0.030901700258255005
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.19509035781625034 -0.98078527328214271 0
+  outer loop
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19509035781625034 -0.98078527328214271 0
+  outer loop
+   vertex -1.8269071304176767e-17 -0.099452190101146698 0.010452846065163612
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.19098421563577417 -0.96014290587992079 -0.20408485898382989
+  outer loop
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.19098433878695739 -0.96014292559861558 -0.2040846509687585
+  outer loop
+   vertex -1.8269071304176767e-17 -0.099452190101146698 -0.010452846065163612
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.17878753433762073 -0.89882617942320464 -0.40018310402734331
+  outer loop
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.17878756859551054 -0.89882619396083963 -0.40018305607006488
+  outer loop
+   vertex -1.7470625291742606e-17 -0.095105648040771484 -0.030901700258255005
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.15887943951689912 -0.79874087880382028 -0.58031916410411344
+  outer loop
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.15887932976663652 -0.7987408154183383 -0.58031928139408939
+  outer loop
+   vertex -1.5908628708195447e-17 -0.086602538824081421 -0.05000000074505806
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.13193484347074247 -0.66328124732023797 -0.73664861639160084
+  outer loop
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.13193484346738296 -0.6632812473181785 -0.73664861639405688
+  outer loop
+   vertex -1.3651348769489291e-17 -0.074314482510089874 -0.06691306084394455
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.098968013678745026 -0.49754554356199898 -0.86177361548731501
+  outer loop
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.098967956160755904 -0.49754551322598684 -0.86177363960732289
+  outer loop
+   vertex -1.0797439998560886e-17 -0.058778524398803711 -0.080901697278022766
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.061351497270056718 -0.30843476568236106 -0.94926497307189694
+  outer loop
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+   vertex -3.819275695072703e-18 -0.020791169255971909 -0.097814761102199554
+   vertex 0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.06135152313811678 -0.30843477395835256 -0.94926496871099864
+  outer loop
+   vertex -7.4716313056158803e-18 -0.040673665702342987 -0.091354548931121826
+   vertex 0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.17471428421919066 -0.26147837970812587 0.9492649660842799
+  outer loop
+   vertex 0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.17471426893077599 -0.26147840938106925 0.9492649607246284
+  outer loop
+   vertex 0.0079564359039068222 -0.019208535552024841 0.097814761102199554
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex 0.01470157690346241 -0.01470157690346241 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.28183684066621417 -0.42179874557711361 0.86177364398829248
+  outer loop
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.28183687150574754 -0.42179864590164712 0.86177368268901633
+  outer loop
+   vertex 0.015565137378871441 -0.037577565759420395 0.091354548931121826
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.37571865044532143 -0.56230267786378618 0.73664862327622749
+  outer loop
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.37571862212216495 -0.56230279592432497 0.73664854760347465
+  outer loop
+   vertex 0.022493567317724228 -0.054304275661706924 0.080901697278022766
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.45245040321610314 -0.67713972638750908 0.5803192428116053
+  outer loop
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.4524503781983546 -0.67713981980897864 0.58031915330896144
+  outer loop
+   vertex 0.028438922017812729 -0.068657629191875458 0.06691306084394455
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.50914415869095786 -0.76198801003014671 0.40018308090319588
+  outer loop
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.50914418433618069 -0.76198794657394719 0.40018316910218049
+  outer loop
+   vertex 0.033141355961561203 -0.080010317265987396 0.05000000074505806
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.54387724854201425 -0.81396988974665174 0.20408468120903095
+  outer loop
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.54387729795136042 -0.81396982149820041 0.20408482173673517
+  outer loop
+   vertex 0.036395356059074402 -0.087866164743900299 0.030901700258255005
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.55557020216110709 -0.83146963292153175 0
+  outer loop
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.55557020216110709 -0.83146963292153175 0
+  outer loop
+   vertex 0.038058705627918243 -0.091881841421127319 0.010452846065163612
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.54387731459104727 -0.81396984640124925 -0.20408467806956454
+  outer loop
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.54387723262956311 -0.81396986593198373 -0.20408481859726049
+  outer loop
+   vertex 0.038058705627918243 -0.091881841421127319 -0.010452846065163612
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.50914420673480953 -0.76198798009585644 -0.40018307677589038
+  outer loop
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.509144138294924 -0.76198797950532793 -0.40018316497487411
+  outer loop
+   vertex 0.036395356059074402 -0.087866164743900299 -0.030901700258255005
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.45245034005942358 -0.67713976273003673 -0.58031924964628023
+  outer loop
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.45245043594349216 -0.67713977536749692 -0.58031916014362273
+  outer loop
+   vertex 0.033141355961561203 -0.080010317265987396 -0.05000000074505806
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.37571857098187661 -0.56230271938745569 -0.7366486321095076
+  outer loop
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.37571869089438792 -0.56230273840009004 -0.73664855643676341
+  outer loop
+   vertex 0.028438922017812729 -0.068657629191875458 -0.06691306084394455
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.28183691468019506 -0.42179871051676798 -0.86177363694298537
+  outer loop
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.28183681079029427 -0.42179870086462851 -0.86177367564370844
+  outer loop
+   vertex 0.022493567317724228 -0.054304275661706924 -0.080901697278022766
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.17471425703507376 -0.26147839157789088 -0.94926496781800662
+  outer loop
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex 0.0079564359039068222 -0.019208535552024841 -0.097814761102199554
+   vertex 0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.17471429029992128 -0.26147838880858149 -0.94926496245835557
+  outer loop
+   vertex 0.015565137378871441 -0.037577565759420395 -0.091354548931121826
+   vertex 0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.26147838880858149 -0.17471429029992128 0.94926496245835557
+  outer loop
+   vertex 0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.26147839157789088 -0.17471425703507376 0.94926496781800662
+  outer loop
+   vertex 0.01470157690346241 -0.01470157690346241 0.097814761102199554
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex 0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.42179870086462851 -0.28183681079029427 0.86177367564370844
+  outer loop
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.42179871051676798 -0.28183691468019506 0.86177363694298537
+  outer loop
+   vertex 0.028760623186826706 -0.028760623186826706 0.091354548931121826
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.56230273840009004 -0.37571869089438792 0.73664855643676341
+  outer loop
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.56230271938745569 -0.37571857098187661 0.7366486321095076
+  outer loop
+   vertex 0.041562695056200027 -0.041562695056200027 0.080901697278022766
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.67713977536749692 -0.45245043594349216 0.58031916014362273
+  outer loop
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.67713976273003673 -0.45245034005942358 0.58031924964628023
+  outer loop
+   vertex 0.052548274397850037 -0.052548274397850037 0.06691306084394455
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.76198797950532793 -0.509144138294924 0.40018316497487411
+  outer loop
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.76198798009585644 -0.50914420673480953 0.40018307677589038
+  outer loop
+   vertex 0.061237242072820663 -0.061237242072820663 0.05000000074505806
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.81396986593198373 -0.54387723262956311 0.20408481859726049
+  outer loop
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.81396984640124925 -0.54387731459104727 0.20408467806956454
+  outer loop
+   vertex 0.067249849438667297 -0.067249849438667297 0.030901700258255005
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.83146963292153175 -0.55557020216110709 0
+  outer loop
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.83146963292153175 -0.55557020216110709 0
+  outer loop
+   vertex 0.070323318243026733 -0.070323318243026733 0.010452846065163612
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.81396982149820041 -0.54387729795136042 -0.20408482173673517
+  outer loop
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.81396988974665174 -0.54387724854201425 -0.20408468120903095
+  outer loop
+   vertex 0.070323318243026733 -0.070323318243026733 -0.010452846065163612
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.76198794657394719 -0.50914418433618069 -0.40018316910218049
+  outer loop
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.76198801003014671 -0.50914415869095786 -0.40018308090319588
+  outer loop
+   vertex 0.067249849438667297 -0.067249849438667297 -0.030901700258255005
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.67713981980897864 -0.4524503781983546 -0.58031915330896144
+  outer loop
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.67713972638750908 -0.45245040321610314 -0.5803192428116053
+  outer loop
+   vertex 0.061237242072820663 -0.061237242072820663 -0.05000000074505806
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.56230279592432497 -0.37571862212216495 -0.73664854760347465
+  outer loop
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.56230267786378618 -0.37571865044532143 -0.73664862327622749
+  outer loop
+   vertex 0.052548274397850037 -0.052548274397850037 -0.06691306084394455
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.42179864590164712 -0.28183687150574754 -0.86177368268901633
+  outer loop
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.42179874557711361 -0.28183684066621417 -0.86177364398829248
+  outer loop
+   vertex 0.041562695056200027 -0.041562695056200027 -0.080901697278022766
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.26147840938106925 -0.17471426893077599 -0.9492649607246284
+  outer loop
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex 0.01470157690346241 -0.01470157690346241 -0.097814761102199554
+   vertex 0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.26147837970812587 -0.17471428421919066 -0.9492649660842799
+  outer loop
+   vertex 0.028760623186826706 -0.028760623186826706 -0.091354548931121826
+   vertex 0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.3084347739583525 -0.061351523138116801 0.94926496871099864
+  outer loop
+   vertex 0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex 0.040673665702342987 0 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.30843476568236111 -0.061351497270056753 0.94926497307189694
+  outer loop
+   vertex 0.019208535552024841 -0.0079564359039068222 0.097814761102199554
+   vertex 0.040673665702342987 0 0.091354548931121826
+   vertex 0.020791169255971909 0 0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.49754551322598684 -0.098967956160755946 0.86177363960732289
+  outer loop
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex 0.058778524398803711 0 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.49754554356199898 -0.098968013678745081 0.86177361548731513
+  outer loop
+   vertex 0.037577565759420395 -0.015565137378871441 0.091354548931121826
+   vertex 0.058778524398803711 0 0.080901697278022766
+   vertex 0.040673665702342987 0 0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.66328124731817861 -0.13193484346738305 0.73664861639405699
+  outer loop
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex 0.074314482510089874 0 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.66328124732023808 -0.13193484347074255 0.73664861639160084
+  outer loop
+   vertex 0.054304275661706924 -0.022493567317724228 0.080901697278022766
+   vertex 0.074314482510089874 0 0.06691306084394455
+   vertex 0.058778524398803711 0 0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.7987408154183383 -0.1588793297666366 0.58031928139408939
+  outer loop
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex 0.086602538824081421 0 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.79874087880382028 -0.15887943951689917 0.58031916410411333
+  outer loop
+   vertex 0.068657629191875458 -0.028438922017812729 0.06691306084394455
+   vertex 0.086602538824081421 0 0.05000000074505806
+   vertex 0.074314482510089874 0 0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.89882619396083974 -0.17878756859551068 0.40018305607006494
+  outer loop
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex 0.095105648040771484 0 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.89882617942320453 -0.17878753433762079 0.40018310402734325
+  outer loop
+   vertex 0.080010317265987396 -0.033141355961561203 0.05000000074505806
+   vertex 0.095105648040771484 0 0.030901700258255005
+   vertex 0.086602538824081421 0 0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.96014292559861558 -0.1909843387869575 0.2040846509687585
+  outer loop
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex 0.099452190101146698 0 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.96014290587992079 -0.19098421563577428 0.20408485898382991
+  outer loop
+   vertex 0.087866164743900299 -0.036395356059074402 0.030901700258255005
+   vertex 0.099452190101146698 0 0.010452846065163612
+   vertex 0.095105648040771484 0 0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.98078527328214282 -0.19509035781625048 0
+  outer loop
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex 0.099452190101146698 0 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.98078527328214282 -0.19509035781625048 0
+  outer loop
+   vertex 0.091881841421127319 -0.038058705627918243 0.010452846065163612
+   vertex 0.099452190101146698 0 -0.010452846065163612
+   vertex 0.099452190101146698 0 0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.96014294936226929 -0.19098422428494741 -0.20408464632156809
+  outer loop
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex 0.095105648040771484 0 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.96014288401665793 -0.19098433051579031 -0.20408485433664575
+  outer loop
+   vertex 0.091881841421127319 -0.038058705627918243 -0.010452846065163612
+   vertex 0.095105648040771484 0 -0.030901700258255005
+   vertex 0.099452190101146698 0 -0.010452846065163612
+  endloop
+ endfacet
+ facet normal 0.89882620092364052 -0.17878753861432078 -0.40018305382588132
+  outer loop
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex 0.086602538824081421 0 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.89882617438269374 -0.17878756470117699 -0.40018310178316374
+  outer loop
+   vertex 0.087866164743900299 -0.036395356059074402 -0.030901700258255005
+   vertex 0.086602538824081421 0 -0.05000000074505806
+   vertex 0.095105648040771484 0 -0.030901700258255005
+  endloop
+ endfacet
+ facet normal 0.79874079057134661 -0.15887942196636892 -0.58031929035065921
+  outer loop
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex 0.074314482510089874 0 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.79874089113149127 -0.15887934482690994 -0.58031917306068981
+  outer loop
+   vertex 0.080010317265987396 -0.033141355961561203 -0.05000000074505806
+   vertex 0.074314482510089874 0 -0.06691306084394455
+   vertex 0.086602538824081421 0 -0.05000000074505806
+  endloop
+ endfacet
+ facet normal 0.66328124731730775 -0.13193484347015969 -0.73664861639434354
+  outer loop
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex 0.058778524398803711 0 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.6632812473204962 -0.13193484346784404 -0.7366486163918875
+  outer loop
+   vertex 0.068657629191875458 -0.028438922017812729 -0.06691306084394455
+   vertex 0.058778524398803711 0 -0.080901697278022766
+   vertex 0.074314482510089874 0 -0.06691306084394455
+  endloop
+ endfacet
+ facet normal 0.49754549605911413 -0.098968004229828863 -0.86177364399826861
+  outer loop
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex 0.040673665702342987 0 -0.091354548931121826
+  endloop
+ endfacet
+ facet normal 0.49754554609711599 -0.098967962699230083 -0.86177361987826373
+  outer loop
+   vertex 0.054304275661706924 -0.022493567317724228 -0.080901697278022766
+   vertex 0.040673665702342987 0 -0.091354548931121826
+   vertex 0.058778524398803711 0 -0.080901697278022766
+  endloop
+ endfacet
+ facet normal 0.30843478276930947 -0.061351500668862545 -0.94926496730034626
+  outer loop
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex 0.019208535552024841 -0.0079564359039068222 -0.097814761102199554
+   vertex 0.020791169255971909 0 -0.097814761102199554
+  endloop
+ endfacet
+ facet normal 0.30843476522401231 -0.061351521400747594 -0.94926497166124379
+  outer loop
+   vertex 0.037577565759420395 -0.015565137378871441 -0.091354548931121826
+   vertex 0.020791169255971909 0 -0.097814761102199554
+   vertex 0.040673665702342987 0 -0.091354548931121826
+  endloop
+ endfacet
+endsolid
diff --git a/apps/gpu/LidDrivenCavityGPU/LidDrivenCavity.cpp b/apps/gpu/LidDrivenCavityGPU/LidDrivenCavity.cpp
index 61b528d4983cc6ec6886eafbae9855b664f506cd..46c0d441bb1a7e26ca855c2c01db8dc1a73d60a7 100644
--- a/apps/gpu/LidDrivenCavityGPU/LidDrivenCavity.cpp
+++ b/apps/gpu/LidDrivenCavityGPU/LidDrivenCavity.cpp
@@ -63,6 +63,8 @@
 #include "VirtualFluids_GPU/LBM/Simulation.h"
 #include "VirtualFluids_GPU/Output/FileWriter.h"
 #include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
+#include "VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h"
 
 //////////////////////////////////////////////////////////////////////////
 
@@ -94,7 +96,7 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
         // Simulation parameters
         //////////////////////////////////////////////////////////////////////////
-        std::string path("/output/DrivenCavity");
+        std::string path("./output/DrivenCavity");
         std::string simulationName("LidDrivenCavity");
 
         const real L        = 1.0;
@@ -103,8 +105,8 @@ int main(int argc, char *argv[])
         const real dt       = (real)0.5e-3;
         const uint nx       = 64;
 
-        const uint timeStepOut = 10000;
-        const uint timeStepEnd = 250000;
+        const uint timeStepOut = 1;
+        const uint timeStepEnd = 10;
 
         // switch between LBM and GKS solver here
         // LbmOrGks lbmOrGks = GKS;
@@ -123,7 +125,9 @@ int main(int argc, char *argv[])
         // setup gridGenerator
         //////////////////////////////////////////////////////////////////////////
 
-        auto gridBuilder = MultipleGridBuilder::makeShared();
+        auto gridFactory = GridFactory::make();
+        gridFactory->setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod::POINT_IN_OBJECT);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
 
         //////////////////////////////////////////////////////////////////////////
         // create grid
@@ -142,8 +146,8 @@ int main(int argc, char *argv[])
         //////////////////////////////////////////////////////////////////////////
 
         if (lbmOrGks == LBM) {
-            SPtr<Parameter> para = Parameter::make();
-
+            SPtr<Parameter> para =std::make_shared<Parameter>();
+            BoundaryConditionFactory bcFactory = BoundaryConditionFactory();
             //////////////////////////////////////////////////////////////////////////
             // compute parameters in lattice units
             //////////////////////////////////////////////////////////////////////////
@@ -188,6 +192,8 @@ int main(int argc, char *argv[])
             gridBuilder->setVelocityBoundaryCondition(SideType::PZ, vx, vy, 0.0);
             gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
 
+            bcFactory.setNoSlipBoundaryCondition(BoundaryConditionFactory::NoSlipBC::NoSlipBounceBack);
+            bcFactory.setVelocityBoundaryCondition(BoundaryConditionFactory::VelocityBC::VelocitySimpleBounceBackCompressible);
             //////////////////////////////////////////////////////////////////////////
             // set copy mesh to simulation
             //////////////////////////////////////////////////////////////////////////
@@ -202,7 +208,7 @@ int main(int argc, char *argv[])
 
             Simulation sim;
             SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
-            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager, &bcFactory);
             sim.run();
             sim.free();
         } else {
diff --git a/src/cpu/VirtualFluidsCore/Grid/Grid3D.cpp b/src/cpu/VirtualFluidsCore/Grid/Grid3D.cpp
index 579301e18508541466467370f6b2085c8e05b7be..9870de686490396261a2515dc3e718856e4b5a90 100644
--- a/src/cpu/VirtualFluidsCore/Grid/Grid3D.cpp
+++ b/src/cpu/VirtualFluidsCore/Grid/Grid3D.cpp
@@ -1257,7 +1257,7 @@ void Grid3D::getSubBlocksZero(int ix1, int ix2, int ix3, int level, vector<SPtr<
         this->getSubBlocksEast(x1W, x2N, x3T, l, blockVector, levelDepth);
 }
 //////////////////////////////////////////////////////////////////////////
-void Grid3D::getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth,
+void Grid3D::getNeighborBlocksForDirectionWithREST(int dir, int ix1, int ix2, int ix3, int level, int levelDepth,
                                                       std::vector<SPtr<Block3D>> &blocks)
 {
     switch (dir) {
diff --git a/src/cpu/VirtualFluidsCore/Grid/Grid3D.h b/src/cpu/VirtualFluidsCore/Grid/Grid3D.h
index af71a9a9e345b4d8608dc5d0ff428e702368d471..b6e4bec96f98afc2872b795c3e9788211cec3e21 100644
--- a/src/cpu/VirtualFluidsCore/Grid/Grid3D.h
+++ b/src/cpu/VirtualFluidsCore/Grid/Grid3D.h
@@ -108,7 +108,7 @@ public:
     void getAllNeighbors(SPtr<Block3D> block, int level, int levelDepth, std::vector<SPtr<Block3D>> &blocks);
     void getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth,
                                        std::vector<SPtr<Block3D>> &blocks);
-    void getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth,
+    void getNeighborBlocksForDirectionWithREST(int dir, int ix1, int ix2, int ix3, int level, int levelDepth,
                                                   std::vector<SPtr<Block3D>> &blocks);
 
     void getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>> &blocks);
diff --git a/src/cpu/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp b/src/cpu/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp
index daed493b9cc1afddbd92acabcd551da0f463ea26..a7f62c3f166e4980a085bfb48373323b436d3d0b 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp
@@ -321,7 +321,7 @@ void CumulantK17LBMKernel::calculate(int step)
                     LBMReal O6 = c1;
 
                     ////////////////////////////////////////////////////////////////////////////////////
-                    //! - A and B: parameters for fourth order convergence of the diffusion term according to Eq. (114) and (115)
+                    //! - A and B: parameters for fourth order convergence of the diffusion term according to Eq. (115) and (116)
                     //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
                     //! with simplifications assuming \f$\omega_2 = 1.0\f$ (modify for different bulk viscosity).
                     //!
diff --git a/src/cuda/CudaGrid.cpp b/src/cuda/CudaGrid.cpp
index c7267972859f04931d9a69cfca073c7ac3267b9f..5c514fcaddfd5b9a68c3ce20fd92e193700890d9 100644
--- a/src/cuda/CudaGrid.cpp
+++ b/src/cuda/CudaGrid.cpp
@@ -7,17 +7,7 @@ namespace vf::cuda
 
 CudaGrid::CudaGrid(unsigned int numberOfThreads, unsigned int numberOfEntities)
 {
-    unsigned int Grid = (numberOfEntities / numberOfThreads) + 1;
-    unsigned int Grid1, Grid2;
-    if (Grid > 512) {
-        Grid1 = 512;
-        Grid2 = (Grid / Grid1) + 1;
-    } else {
-        Grid1 = 1;
-        Grid2 = Grid;
-    }
-    
-    grid = dim3(Grid1, Grid2);
+    grid = getCudaGrid( numberOfThreads, numberOfEntities);
     threads = dim3(numberOfThreads, 1, 1);
 }
 
@@ -27,4 +17,22 @@ void CudaGrid::print() const
 }
 
 
+dim3 getCudaGrid(const unsigned int numberOfThreads, const unsigned int numberOfEntities){
+   int Grid = (numberOfEntities / numberOfThreads) + 1;
+   int Grid1, Grid2;
+   if (Grid > 512)
+   {
+      Grid1 = 512;
+      Grid2 = (Grid/Grid1)+1;
+   }
+   else
+   {
+      Grid1 = 1;
+      Grid2 = Grid;
+   }
+   dim3 cudaGrid(Grid1, Grid2);
+   return cudaGrid;
+}
+
+
 }
diff --git a/src/cuda/CudaGrid.h b/src/cuda/CudaGrid.h
index a9926c3861749f648da529f2b45554d13599a302..bf82077fdf6c9a5494a35950a917d9aaf1047b56 100644
--- a/src/cuda/CudaGrid.h
+++ b/src/cuda/CudaGrid.h
@@ -18,6 +18,7 @@ struct CudaGrid
     void print() const;
 };
 
+dim3 getCudaGrid(const unsigned int numberOfThreads, const unsigned int numberOfEntities);
 
 }
 
diff --git a/src/gpu/GksMeshAdapter/GksMeshAdapter.cpp b/src/gpu/GksMeshAdapter/GksMeshAdapter.cpp
index 34b66440c564890ea9656aad043b9f666cd3a649..4e513a50068ffa6d56d538e13efadfdbc2ddebbf 100644
--- a/src/gpu/GksMeshAdapter/GksMeshAdapter.cpp
+++ b/src/gpu/GksMeshAdapter/GksMeshAdapter.cpp
@@ -54,11 +54,14 @@
 #include "MeshFace.h"
 
 #include <lbm/constants/NumericConstants.h>
+#include "lbm/constants/D3Q27.h"
 
-using namespace vf::lbm::constant;
 
+using namespace vf::lbm::dir;
+using namespace vf::lbm::constant;
 using namespace vf::gpu;
 
+
 GksMeshAdapter::GksMeshAdapter(SPtr<MultipleGridBuilder> gridBuilder)
     : gridBuilder(gridBuilder)
 {}
@@ -167,7 +170,7 @@ void GksMeshAdapter::findCellToCellConnectivity()
 
         for( uint idx = 0; idx < 27; idx++ )
         {
-            if( idx == DIR_27_ZERO ) continue;
+            if( idx == vf::lbm::dir::REST ) continue;
 
             int xSign = dirs.directions[idx][0];
             int ySign = dirs.directions[idx][1];
diff --git a/src/gpu/GridGenerator/CMakeLists.txt b/src/gpu/GridGenerator/CMakeLists.txt
index 07b6125d6ecd83dca59e20e7c286ebc2b8d14715..7483d276d08bb66b8c6948689f1dbb13f8846cb6 100644
--- a/src/gpu/GridGenerator/CMakeLists.txt
+++ b/src/gpu/GridGenerator/CMakeLists.txt
@@ -1,6 +1,7 @@
 project(GridGenerator LANGUAGES CXX)
 
 vf_add_library(PRIVATE_LINK basics OpenMP::OpenMP_CXX)
+vf_add_tests()
 
 if(NOT MSVC) 
    target_compile_options(GridGenerator PRIVATE "-Wno-strict-aliasing")
diff --git a/src/gpu/GridGenerator/geometries/Arrow/ArrowImp.h b/src/gpu/GridGenerator/geometries/Arrow/ArrowImp.h
index ef145b7def48803b7e2d043f7a5862ee21f954c4..1fb509e0c6092dd3f00d4abf1849014191425db2 100644
--- a/src/gpu/GridGenerator/geometries/Arrow/ArrowImp.h
+++ b/src/gpu/GridGenerator/geometries/Arrow/ArrowImp.h
@@ -36,7 +36,6 @@
 #include <memory>
 
 #include "global.h"
-#include "GridGenerator_export.h"
 
 #include "Arrow.h"
 
diff --git a/src/gpu/GridGenerator/geometries/BoundingBox/BoundingBoxTest.cpp b/src/gpu/GridGenerator/geometries/BoundingBox/BoundingBoxTest.cpp
index f982b2fa5d5c614ded87ba2a03f6e71d72bf130c..67ac560b91f0ae712dfbc67d22676d8af8fc9afe 100644
--- a/src/gpu/GridGenerator/geometries/BoundingBox/BoundingBoxTest.cpp
+++ b/src/gpu/GridGenerator/geometries/BoundingBox/BoundingBoxTest.cpp
@@ -1,13 +1,19 @@
 #include "gmock/gmock.h"
 
-#include <GridGenerator/geometries/Triangle/Triangle.h>
-#include <GridGenerator/geometries/BoundingBox/BoundingBox.h>
-#include <GridGenerator/geometries/Vertex/Vertex.h>
-
+#include "geometries/Triangle/Triangle.h"
+#include "geometries/BoundingBox/BoundingBox.h"
+#include "geometries/Vertex/Vertex.h"
+
+auto RealEq = [](auto value) { 
+#ifdef VF_DOUBLE_ACCURACY
+    return testing::DoubleEq(value); 
+#else 
+    return testing::FloatEq(value);
+#endif
+};
 
 using namespace testing;
 
-
 TEST(BoundingBoxExactTest, findMinMaxFromTriangle)
 {
     BoundingBox box = BoundingBox::makeInvalidMinMaxBox();
@@ -19,7 +25,11 @@ TEST(BoundingBoxExactTest, findMinMaxFromTriangle)
     real maxX = 110.0f;
     real maxY = 50.0f;
     real maxZ = 12122.23f;
-    Triangle t = Triangle(Vertex(maxX, maxY - 10, minZ + 2), Vertex(minX, maxY, maxZ), Vertex(minX + 3, minY, minZ), Vertex(0.0f, 0.0f, 0.0f));
+    Vertex v1 = Vertex(maxX, maxY - 10, minZ + 2);
+    Vertex v2 =  Vertex(minX, maxY, maxZ);
+    Vertex v3 = Vertex(minX + 3, minY, minZ);
+    Vertex normal = Vertex(0.0f, 0.0f, 0.0f);
+    Triangle t = Triangle(v1, v2, v3, normal);
 
 	box.setMinMax(t);
 
@@ -44,7 +54,11 @@ TEST(BoundingBoxTest, isInside_true)
     box.maxY = 10.0f;
     box.maxZ = 10.0f;
 
-    Triangle t = Triangle(Vertex(1,1,1), Vertex(2,2,2), Vertex(3,3,3), Vertex(0.0f, 0.0f, 0.0f));
+    Vertex v1 = Vertex(1,1,1);
+    Vertex v2 =  Vertex(2,2,2);
+    Vertex v3 = Vertex(3,3,3);
+    Vertex normal = Vertex(0.0f, 0.0f, 0.0f);
+    Triangle t = Triangle(v1, v2, v3, normal);
 
     EXPECT_TRUE(box.isInside(t));
 }
@@ -61,7 +75,11 @@ TEST(BoundingBoxTest, isInside_false)
     box.maxY = 10.0f;
     box.maxZ = 10.0f;
 
-    Triangle t = Triangle(Vertex(1, 1, 1), Vertex(2, 2, 2), Vertex(3, 3, 11), Vertex(0.0f, 0.0f, 0.0f));
+    Vertex v1 = Vertex(1,1,1);
+    Vertex v2 =  Vertex(2,2,2);
+    Vertex v3 = Vertex(3,3,11);
+    Vertex normal = Vertex(0.0f, 0.0f, 0.0f);
+    Triangle t = Triangle(v1, v2, v3, normal);
 
     EXPECT_FALSE(box.isInside(t));
 }
diff --git a/src/gpu/GridGenerator/geometries/Cuboid/Cuboid.cpp b/src/gpu/GridGenerator/geometries/Cuboid/Cuboid.cpp
index e64a202ca9bcd5a33fcc9ba85e7bd35fa67a1d4e..7b0dbcdbdcbd679f1eb47ed5db7d828da8c31767 100644
--- a/src/gpu/GridGenerator/geometries/Cuboid/Cuboid.cpp
+++ b/src/gpu/GridGenerator/geometries/Cuboid/Cuboid.cpp
@@ -113,18 +113,12 @@ double Cuboid::getMaximum(double x1, double x2)
 bool Cuboid::isPointInObject(const double& x1, const double& x2, const double& x3, const double& minOffset, const double& maxOffset)
 {
     //false, if 'not in Object' or 'on Boundary'!
-    if (vf::Math::lessEqual((real)x1, (real)this->getX1Minimum() + (real)minOffset))
-        return false;
-    if (vf::Math::lessEqual((real)x2, (real)this->getX2Minimum() + (real)minOffset))
-        return false;
-    if (vf::Math::lessEqual((real)x3, (real)this->getX3Minimum() + (real)minOffset))
-        return false;
-    if (vf::Math::greaterEqual((real)x1, (real)this->getX1Maximum() - (real)maxOffset))
-        return false;
-    if (vf::Math::greaterEqual((real)x2, (real)this->getX2Maximum() - (real)maxOffset))
-        return false;
-    if (vf::Math::greaterEqual((real)x3, (real)this->getX3Maximum() - (real)maxOffset))
-        return false;
+    if (vf::Math::lessEqual(   (real)x1, (real)this->getX1Minimum() + (real)minOffset))  return false;
+    if (vf::Math::lessEqual(   (real)x2, (real)this->getX2Minimum() + (real)minOffset))  return false;
+    if (vf::Math::lessEqual(   (real)x3, (real)this->getX3Minimum() + (real)minOffset))  return false;
+    if (vf::Math::greaterEqual((real)x1, (real)this->getX1Maximum() - (real)maxOffset))  return false;
+    if (vf::Math::greaterEqual((real)x2, (real)this->getX2Maximum() - (real)maxOffset))  return false;
+    if (vf::Math::greaterEqual((real)x3, (real)this->getX3Maximum() - (real)maxOffset))  return false;
 
     return true;
 }
diff --git a/src/gpu/GridGenerator/geometries/Sphere/Sphere.h b/src/gpu/GridGenerator/geometries/Sphere/Sphere.h
index ba5821f5bfed5b4d25c1ee3c5abecb168db462e7..03b9ef9fd101f19dbaff7d4e4109000cce6e3c49 100644
--- a/src/gpu/GridGenerator/geometries/Sphere/Sphere.h
+++ b/src/gpu/GridGenerator/geometries/Sphere/Sphere.h
@@ -34,7 +34,6 @@
 #define SPHERE_H
 
 #include "global.h"
-#include "GridGenerator_export.h"
 #include "geometries/Object.h"
 
 class GRIDGENERATOR_EXPORT Sphere : public Object
diff --git a/src/gpu/GridGenerator/geometries/Triangle/Triangle.h b/src/gpu/GridGenerator/geometries/Triangle/Triangle.h
index 0017d2f71145f2608976a95018816bf81cef44b7..0c62f2c0db5ced3c749c2ffd6196087192aab3df 100644
--- a/src/gpu/GridGenerator/geometries/Triangle/Triangle.h
+++ b/src/gpu/GridGenerator/geometries/Triangle/Triangle.h
@@ -36,7 +36,6 @@
 #include <memory>
 
 #include "global.h"
-#include "GridGenerator_export.h"
 #include "geometries/Vertex/Vertex.h"
 
 class TriangleMemento;
diff --git a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMesh.h b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMesh.h
index 2d31de98bf1f5530ada555e548ac6bb40e5e51b7..beb1c3a05b25904446e72a62196bcf6213fb0691 100644
--- a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMesh.h
+++ b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMesh.h
@@ -37,7 +37,6 @@
 #include <vector>
 #include <string>
 #include <memory>
-#include "GridGenerator_export.h"
 #include "global.h"
 
 #include "geometries/Triangle/Triangle.h"
diff --git a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
index 573a464844ac769ebd1127c666481b87f363099f..b98d531599ff897da0ad596a7d46e1393a456aac 100644
--- a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
+++ b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.h
@@ -34,7 +34,6 @@
 #define TriangularMeshStrategy_H
 
 #include "global.h"
-#include "GridGenerator_export.h"
 
 class GridImp;
 class TriangularMesh;
diff --git a/src/gpu/GridGenerator/geometries/TriangularMesh/triangleNeighborFinder/TriangleNeighborFinder.h b/src/gpu/GridGenerator/geometries/TriangularMesh/triangleNeighborFinder/TriangleNeighborFinder.h
index b0dda279c5f95a621b5875e78b5cdb7479b98a54..2b42ff3ad2dacaade3bbc8da4f6d4b3c61b14442 100644
--- a/src/gpu/GridGenerator/geometries/TriangularMesh/triangleNeighborFinder/TriangleNeighborFinder.h
+++ b/src/gpu/GridGenerator/geometries/TriangularMesh/triangleNeighborFinder/TriangleNeighborFinder.h
@@ -33,8 +33,7 @@
 #ifndef TriangleNeighborFinder_h
 #define TriangleNeighborFinder_h
 
-#include "GridGenerator/global.h"
-#include "GridGenerator_export.h"
+#include "global.h"
 #include <vector>
 
 struct IDS {
diff --git a/src/gpu/GridGenerator/geometries/Vertex/Vertex.h b/src/gpu/GridGenerator/geometries/Vertex/Vertex.h
index 7b27d853f652459143699204c59a5843de6eaf39..ec5fc0f1ced64f7757de26deaf3053504e29d7c6 100644
--- a/src/gpu/GridGenerator/geometries/Vertex/Vertex.h
+++ b/src/gpu/GridGenerator/geometries/Vertex/Vertex.h
@@ -37,7 +37,7 @@
 #include <memory>
 #include <ostream>
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 struct GRIDGENERATOR_EXPORT Vertex
 {
diff --git a/src/gpu/GridGenerator/geometries/VerticalCylinder/VerticalCylinder.h b/src/gpu/GridGenerator/geometries/VerticalCylinder/VerticalCylinder.h
index 24d9383bf5628e46b1d634874f79ceb73eaa6cae..e995d2ba16eba17930401c99c260f81b9c6077b4 100644
--- a/src/gpu/GridGenerator/geometries/VerticalCylinder/VerticalCylinder.h
+++ b/src/gpu/GridGenerator/geometries/VerticalCylinder/VerticalCylinder.h
@@ -34,7 +34,6 @@
 #define VERTICAL_CYLINDER_H
 
 #include "global.h"
-#include "GridGenerator_export.h"
 #include "geometries/Object.h"
 
 class GRIDGENERATOR_EXPORT VerticalCylinder : public Object
diff --git a/src/gpu/GridGenerator/global.h b/src/gpu/GridGenerator/global.h
index 19bedc95b9a767f30761279500c6b8c036509eba..04f7e71e84d2c287493c18565bd39501aa031d72 100644
--- a/src/gpu/GridGenerator/global.h
+++ b/src/gpu/GridGenerator/global.h
@@ -43,9 +43,9 @@
 
 #include "GridGenerator_export.h"
 
-#include "PointerDefinitions.h"
-#include "Core/DataTypes.h"
+#include "basics/PointerDefinitions.h"
+#include "basics/Core/DataTypes.h"
 
-#include "Core/Logger/Logger.h"
+#include "basics/Core/Logger/Logger.h"
 
 #endif 
diff --git a/src/gpu/GridGenerator/grid/BoundaryConditions/Side.cpp b/src/gpu/GridGenerator/grid/BoundaryConditions/Side.cpp
index 4c5161acb778c05402301a10462220aeea5e73f4..330f400b34473102c0bbe4b2e80d3d5272dd1d3c 100644
--- a/src/gpu/GridGenerator/grid/BoundaryConditions/Side.cpp
+++ b/src/gpu/GridGenerator/grid/BoundaryConditions/Side.cpp
@@ -53,7 +53,7 @@ void Side::addIndices(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition
                                             || grid->getFieldEntry(index) == vf::gpu::FLUID_CFC
                                             || grid->getFieldEntry(index) == vf::gpu::FLUID_CFF
                                             || grid->getFieldEntry(index) == vf::gpu::FLUID_FCC
-                                            || grid->getFieldEntry(index) == vf::gpu::FLUID_FCF ) )
+                                            || grid->getFieldEntry(index) == vf::gpu::FLUID_FCF ))
             {
                 grid->setFieldEntry(index, boundaryCondition->getType());
                 boundaryCondition->indices.push_back(index);
@@ -133,6 +133,7 @@ void Side::setQs(SPtr<Grid> grid, SPtr<BoundaryCondition> boundaryCondition, uin
             qNode[dir] = 0.5;
         else
             qNode[dir] = -1.0;
+
     }
 
     boundaryCondition->qs.push_back(qNode);
@@ -149,6 +150,7 @@ uint Side::getIndex(SPtr<Grid> grid, std::string coord, real constant, real v1,
     return INVALID_INDEX;
 }
 
+
 void Geometry::addIndices(std::vector<SPtr<Grid> > grids, uint level, SPtr<BoundaryCondition> boundaryCondition)
 {
     auto geometryBoundaryCondition = std::dynamic_pointer_cast<GeometryBoundaryCondition>(boundaryCondition);
@@ -188,6 +190,8 @@ void Geometry::addIndices(std::vector<SPtr<Grid> > grids, uint level, SPtr<Bound
     }
 }
 
+
+
 void MX::addIndices(std::vector<SPtr<Grid> > grid, uint level, SPtr<BoundaryCondition> boundaryCondition)
 {
     real startInner = grid[level]->getStartY();
@@ -277,6 +281,6 @@ void PZ::addIndices(std::vector<SPtr<Grid> > grid, uint level, SPtr<BoundaryCond
     real coordinateNormal = grid[level]->getEndZ() - grid[level]->getDelta();
 
     if( coordinateNormal < grid[0]->getEndZ() - grid[0]->getDelta() ) return;
-
+    
     Side::addIndices(grid[level], boundaryCondition, "z", coordinateNormal, startInner, endInner, startOuter, endOuter);
 }
diff --git a/src/gpu/GridGenerator/grid/Cell.h b/src/gpu/GridGenerator/grid/Cell.h
index a7a64917025742217be88e7ebe1ccc9e669fc7c0..f39bd4a7bb13be0d768e092276194e6bad16dcff 100644
--- a/src/gpu/GridGenerator/grid/Cell.h
+++ b/src/gpu/GridGenerator/grid/Cell.h
@@ -33,7 +33,7 @@
 #ifndef CELL_H
 #define CELL_H
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 struct Point
 {
diff --git a/src/gpu/GridGenerator/grid/Field.h b/src/gpu/GridGenerator/grid/Field.h
index 002c8c108bd405f4077cd2779f5e59232135ace9..08fff6da7c5a3f431138dc5039b4d234493ae4b8 100644
--- a/src/gpu/GridGenerator/grid/Field.h
+++ b/src/gpu/GridGenerator/grid/Field.h
@@ -33,7 +33,7 @@
 #ifndef FIELD_H
 #define FIELD_H
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 struct Vertex;
 
diff --git a/src/gpu/GridGenerator/grid/Grid.h b/src/gpu/GridGenerator/grid/Grid.h
index 3407b23c1efbb4143d06ded7880c26d7c0eb6599..4dcc99c169b269be4dc81a73cfb36e187036f8a2 100644
--- a/src/gpu/GridGenerator/grid/Grid.h
+++ b/src/gpu/GridGenerator/grid/Grid.h
@@ -28,18 +28,18 @@
 //
 //! \file Grid.h
 //! \ingroup grid
-//! \author Soeren Peters, Stephan Lenz, Martin Schönherr
+//! \author Soeren Peters, Stephan Lenz, Martin Sch�nherr
 //=======================================================================================
 #ifndef GRID_H
 #define GRID_H
 
 #include "Core/LbmOrGks.h"
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
-#include "geometries/Vertex/Vertex.h"
+#include "gpu/GridGenerator/geometries/Vertex/Vertex.h"
 
-#include "grid/Cell.h"
+#include "gpu/GridGenerator/grid/Cell.h"
 
 class TriangularMesh;
 struct Vertex;
@@ -165,7 +165,7 @@ public:
     virtual uint getSendIndex(int direction, uint index)    = 0;
     virtual uint getReceiveIndex(int direction, uint index) = 0;
 
-    virtual void repairCommunicationInices(int direction) = 0;
+    virtual void repairCommunicationIndices(int direction) = 0;
 
 };
 
diff --git a/src/gpu/GridGenerator/grid/GridBuilder/GridBuilder.h b/src/gpu/GridGenerator/grid/GridBuilder/GridBuilder.h
index 57290025c3f6e48554e1dafe9bd101ae237b3288..90713bfef308d0410a32d67aad4b2bea56a19169 100644
--- a/src/gpu/GridGenerator/grid/GridBuilder/GridBuilder.h
+++ b/src/gpu/GridGenerator/grid/GridBuilder/GridBuilder.h
@@ -28,7 +28,7 @@
 //
 //! \file GridBuilder.h
 //! \ingroup grid
-//! \author Soeren Peters, Stephan Lenz, Martin Schönherr
+//! \author Soeren Peters, Stephan Lenz, Martin Sch�nherr
 //=======================================================================================
 #ifndef GridBuilder_H
 #define GridBuilder_H
@@ -37,7 +37,7 @@
 #include <string>
 #include <memory>
 
-#include "GridGenerator/global.h"
+#include "gpu/GridGenerator/global.h"
 
 #define GEOMQS 6
 #define INLETQS 0
@@ -124,5 +124,4 @@ public:
     virtual void getReceiveIndices(int *sendIndices, int direction, int level) = 0;
 };
 
-#endif
-
+#endif
\ No newline at end of file
diff --git a/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp b/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
index aa593ad7ffc4daecb3a05ab0cc41865a09594933..41d2cf5af9af2029c0200e4aae311e2a7717c6cb 100644
--- a/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
+++ b/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.cpp
@@ -34,6 +34,7 @@
 
 #include <stdio.h>
 #include <iostream>
+#include <algorithm>
 
 #include "geometries/Arrow/ArrowImp.h"
 #include "geometries/BoundingBox/BoundingBox.h"
@@ -84,7 +85,6 @@ void LevelGridBuilder::setSlipBoundaryCondition(SideType sideType, real nomalX,
     slipBoundaryCondition->side->addIndices(grids, 0, slipBoundaryCondition);
 
     slipBoundaryCondition->fillSlipNormalLists();
-
     boundaryConditions[0]->slipBoundaryConditions.push_back(slipBoundaryCondition);
 
     *logging::out << logging::Logger::INFO_INTERMEDIATE << "Set Slip BC on level " << 0 << " with " << (int)slipBoundaryCondition->indices.size() << "\n";
@@ -96,38 +96,41 @@ void LevelGridBuilder::setVelocityBoundaryCondition(SideType sideType, real vx,
         setVelocityGeometryBoundaryCondition(vx, vy, vz);
     else
     {
-        SPtr<VelocityBoundaryCondition> velocityBoundaryCondition = VelocityBoundaryCondition::make(vx, vy, vz);
+        for (uint level = 0; level < getNumberOfGridLevels(); level++)
+        {
+            SPtr<VelocityBoundaryCondition> velocityBoundaryCondition = VelocityBoundaryCondition::make(vx, vy, vz);
 
-        auto side = SideFactory::make(sideType);
+            auto side = SideFactory::make(sideType);
 
-        velocityBoundaryCondition->side = side;
-        velocityBoundaryCondition->side->addIndices(grids, 0, velocityBoundaryCondition);
+            velocityBoundaryCondition->side = side;
+            velocityBoundaryCondition->side->addIndices(grids, level, velocityBoundaryCondition);
 
-        velocityBoundaryCondition->fillVelocityLists();
+            velocityBoundaryCondition->fillVelocityLists();
 
-        boundaryConditions[0]->velocityBoundaryConditions.push_back(velocityBoundaryCondition);
+            boundaryConditions[level]->velocityBoundaryConditions.push_back(velocityBoundaryCondition);
 
-        *logging::out << logging::Logger::INFO_INTERMEDIATE << "Set Velocity BC on level " << 0 << " with " << (int)velocityBoundaryCondition->indices.size() <<"\n";
+            *logging::out << logging::Logger::INFO_INTERMEDIATE << "Set Velocity BC on level " << level << " with " << (int)velocityBoundaryCondition->indices.size() <<"\n";
+        }
     }
 }
 
 void LevelGridBuilder::setVelocityGeometryBoundaryCondition(real vx, real vy, real vz)
 {
     geometryHasValues = true;
-    
+
     for (uint level = 0; level < getNumberOfGridLevels(); level++)
     {
-        if (boundaryConditions[level]->geometryBoundaryCondition != nullptr)
-        {
-            boundaryConditions[level]->geometryBoundaryCondition->vx = vx;
-            boundaryConditions[level]->geometryBoundaryCondition->vy = vy;
-            boundaryConditions[level]->geometryBoundaryCondition->vz = vz;
-            boundaryConditions[level]->geometryBoundaryCondition->side->addIndices(grids, level, boundaryConditions[level]->geometryBoundaryCondition);
+		if (boundaryConditions[level]->geometryBoundaryCondition != nullptr)
+		{
+			boundaryConditions[level]->geometryBoundaryCondition->vx = vx;
+			boundaryConditions[level]->geometryBoundaryCondition->vy = vy;
+			boundaryConditions[level]->geometryBoundaryCondition->vz = vz;
+			boundaryConditions[level]->geometryBoundaryCondition->side->addIndices(grids, level, boundaryConditions[level]->geometryBoundaryCondition);
 
             boundaryConditions[level]->geometryBoundaryCondition->fillVelocityLists();
 
             *logging::out << logging::Logger::INFO_INTERMEDIATE << "Set Geometry Velocity BC on level " << level << " with " << (int)boundaryConditions[level]->geometryBoundaryCondition->indices.size() <<"\n";
-        }
+		}
     }
 }
 
@@ -166,8 +169,7 @@ void LevelGridBuilder::setNoSlipBoundaryCondition(SideType sideType)
 
         noSlipBoundaryCondition->fillVelocityLists();
 
-        // effectively just a wrapper for velocityBC with zero velocity. No distinction in GridGenerator.
-        boundaryConditions[level]->velocityBoundaryConditions.push_back(noSlipBoundaryCondition);
+        boundaryConditions[level]->velocityBoundaryConditions.push_back(noSlipBoundaryCondition); //now effectively just a wrapper for velocityBC with zero velocity. No distinction in Gridgenerator.
     }
 }
 
@@ -293,7 +295,6 @@ uint LevelGridBuilder::getNumberOfNodes(unsigned int level) const
     return grids[level]->getSparseSize();
 }
 
-
 std::shared_ptr<Grid> LevelGridBuilder::getGrid(int level, int box)
 {
     return this->grids[level];
diff --git a/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h b/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
index b4a461ec764d0a97efd83ec7f4899814fe99a489..8be699c09e7ea5f37df91a76bbd4bdeed342ce4f 100644
--- a/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
+++ b/src/gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h
@@ -38,11 +38,12 @@
 #include <memory>
 #include <array>
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
-#include "grid/GridBuilder/GridBuilder.h"
-#include "grid/Grid.h"
-#include "grid/NodeValues.h"
+#include "gpu/GridGenerator/grid/GridBuilder/GridBuilder.h"
+#include "gpu/GridGenerator/grid/Grid.h"
+#include "gpu/GridGenerator/grid/GridInterface.h"
+#include "gpu/GridGenerator/grid/NodeValues.h"
 
 struct Vertex;
 class  Grid;
@@ -54,6 +55,7 @@ class BoundingBox;
 class Side;
 class VelocityBoundaryCondition;
 class SlipBoundaryCondition;
+class StressBoundaryCondition;
 class PressureBoundaryCondition;
 class GeometryBoundaryCondition;
 enum class SideType;
@@ -127,6 +129,8 @@ protected:
 
         std::vector<SPtr<SlipBoundaryCondition>> slipBoundaryConditions;
 
+        std::vector<SPtr<StressBoundaryCondition>> stressBoundaryConditions;
+
         std::vector<SPtr<VelocityBoundaryCondition>> velocityBoundaryConditions;
 
         std::vector<SPtr<PressureBoundaryCondition>> pressureBoundaryConditions;
diff --git a/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp b/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
index c36a8cb70e6bb36dccb9179b9c014e5fb7464a30..da18a883181069f089e7232c9cd1b4f19cc9dc35 100644
--- a/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
+++ b/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.cpp
@@ -49,14 +49,14 @@
 #include "io/GridVTKWriter/GridVTKWriter.h"
 #include "io/STLReaderWriter/STLWriter.h"
 
-MultipleGridBuilder::MultipleGridBuilder() : LevelGridBuilder(), numberOfLayersFine(12), numberOfLayersBetweenLevels(8), subDomainBox(nullptr)
+MultipleGridBuilder::MultipleGridBuilder(SPtr<GridFactory> gridFactory) : LevelGridBuilder(), gridFactory(gridFactory), numberOfLayersFine(12), numberOfLayersBetweenLevels(8), subDomainBox(nullptr)
 {
 
 }
 
-SPtr<MultipleGridBuilder> MultipleGridBuilder::makeShared()
+SPtr<MultipleGridBuilder> MultipleGridBuilder::makeShared(SPtr<GridFactory> gridFactory)
 {
-    return SPtr<MultipleGridBuilder>(new MultipleGridBuilder());
+    return SPtr<MultipleGridBuilder>(new MultipleGridBuilder(gridFactory));
 }
 
 void MultipleGridBuilder::addCoarseGrid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta)
@@ -195,7 +195,7 @@ void MultipleGridBuilder::addGridToListIfValid(SPtr<Grid> grid)
 
 SPtr<Grid> MultipleGridBuilder::makeGrid(Object* gridShape, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, uint level) const
 {
-    return GridImp::makeShared(gridShape, startX, startY, startZ, endX, endY, endZ, delta, "D3Q27", level);
+    return gridFactory->makeGrid(gridShape, startX, startY, startZ, endX, endY, endZ, delta, level);
 }
 
 bool MultipleGridBuilder::coarseGridExists() const
diff --git a/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h b/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h
index 839e0036bbc6b0f5d28bec5da3a0abe637b7adca..9627fb0bf7e97a925d4b0ba2c450c507426a48f4 100644
--- a/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h
+++ b/src/gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h
@@ -41,6 +41,7 @@
 #include "global.h"
 
 #include "grid/GridBuilder/LevelGridBuilder.h"
+#include "grid/GridFactory.h"
 #include "grid/distributions/Distribution.h"
 
 class Object;
@@ -49,10 +50,10 @@ class BoundingBox;
 class MultipleGridBuilder : public LevelGridBuilder
 {
 private:
-    GRIDGENERATOR_EXPORT MultipleGridBuilder();
+    GRIDGENERATOR_EXPORT MultipleGridBuilder(SPtr<GridFactory> gridFactory);
 
 public:
-    GRIDGENERATOR_EXPORT static SPtr<MultipleGridBuilder> makeShared();
+    GRIDGENERATOR_EXPORT static SPtr<MultipleGridBuilder> makeShared(SPtr<GridFactory> gridFactory);
 
     GRIDGENERATOR_EXPORT void addCoarseGrid(real startX, real startY, real startZ, real endX, real endY, real endZ, real delta);
     GRIDGENERATOR_EXPORT void addGrid(Object *gridShape);
@@ -103,6 +104,7 @@ private:
     static void emitNoCoarseGridExistsWarning();
     static void emitGridIsNotInCoarseGridWarning();
 
+    SPtr<GridFactory> gridFactory;
     Object *solidObject = nullptr;
 
     uint numberOfLayersFine;
diff --git a/src/gpu/GridGenerator/grid/GridFactory.h b/src/gpu/GridGenerator/grid/GridFactory.h
index b525596fa670a026d60b1297c75ef69c46b23498..53d358d5325390394f1d38694de605e5cc0d2f56 100644
--- a/src/gpu/GridGenerator/grid/GridFactory.h
+++ b/src/gpu/GridGenerator/grid/GridFactory.h
@@ -36,6 +36,7 @@
 #include "global.h"
 
 #include "geometries/Cuboid/Cuboid.h"
+#include "geometries/TriangularMesh/TriangularMeshStrategy.h"
 
 #include "grid/GridImp.h"
 
@@ -54,8 +55,33 @@ public:
 
     SPtr<Grid> makeGrid(Object* gridShape, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, uint level, const std::string& d3Qxx = "D3Q27")
     {
-        return GridImp::makeShared(gridShape, startX, startY, startZ, endX, endY, endZ, delta, d3Qxx, level);
+        SPtr<GridImp> grid;
+        
+        grid = GridImp::makeShared(gridShape, startX, startY, startZ, endX, endY, endZ, delta, d3Qxx, level);
+
+        grid->setTriangularMeshDiscretizationStrategy(new PointInObjectDiscretizationStrategy());
+
+        return grid;
+    }
+
+    void setTriangularMeshDiscretizationMethod(TriangularMeshDiscretizationMethod triangularMeshDiscretizationMethod)
+    {
+        switch (triangularMeshDiscretizationMethod)
+        {
+        case TriangularMeshDiscretizationMethod::POINT_UNDER_TRIANGLE:
+            triangularMeshDiscretizationStrategy = new PointUnderTriangleStrategy();
+            break;
+        case TriangularMeshDiscretizationMethod::RAYCASTING:
+            triangularMeshDiscretizationStrategy = new RayCastingDiscretizationStrategy();
+            break;
+        case TriangularMeshDiscretizationMethod::POINT_IN_OBJECT:
+            triangularMeshDiscretizationStrategy = new PointInObjectDiscretizationStrategy();
+            break;
+        }
     }
+
+private:
+    TriangularMeshDiscretizationStrategy* triangularMeshDiscretizationStrategy;
 };
 
 
diff --git a/src/gpu/GridGenerator/grid/GridImp.cpp b/src/gpu/GridGenerator/grid/GridImp.cpp
index 0d1a6c3472309ff030e764e4690fc8631ddcee61..66d90b82d670c1d7bb72644a1e8e19829a4e1da4 100644
--- a/src/gpu/GridGenerator/grid/GridImp.cpp
+++ b/src/gpu/GridGenerator/grid/GridImp.cpp
@@ -37,6 +37,7 @@
 #include <iostream>
 #include <omp.h>
 #include <sstream>
+# include <algorithm>
 #include <cmath>
 
 #include "global.h"
@@ -160,24 +161,24 @@ void GridImp::inital(const SPtr<Grid> fineGrid, uint numberOfLayers)
 #pragma omp parallel for
         for (int xIdx = 0; xIdx < (int)this->nx; xIdx++) {
             for (uint yIdx = 0; yIdx < this->ny; yIdx++) {
-                this->fixRefinementIntoWall(xIdx, yIdx, 0, 3);
-                this->fixRefinementIntoWall(xIdx, yIdx, this->nz - 1, -3);
+                this->fixRefinementIntoWall( xIdx, yIdx, 0           ,  3 );
+                this->fixRefinementIntoWall( xIdx, yIdx, this->nz - 1, -3 );
             }
         }
 
 #pragma omp parallel for
         for (int xIdx = 0; xIdx < (int)this->nx; xIdx++) {
             for (uint zIdx = 0; zIdx < this->nz; zIdx++) {
-                this->fixRefinementIntoWall(xIdx, 0, zIdx, 2);
-                this->fixRefinementIntoWall(xIdx, this->ny - 1, zIdx, -2);
+                this->fixRefinementIntoWall( xIdx, 0           , zIdx,  2 );
+                this->fixRefinementIntoWall( xIdx, this->ny - 1, zIdx, -2 );
             }
         }
 
 #pragma omp parallel for
         for (int yIdx = 0; yIdx < (int)this->ny; yIdx++) {
             for (uint zIdx = 0; zIdx < this->nz; zIdx++) {
-                this->fixRefinementIntoWall(0, yIdx, zIdx, 1);
-                this->fixRefinementIntoWall(this->nx - 1, yIdx, zIdx, -1);
+                this->fixRefinementIntoWall( 0           , yIdx, zIdx,  1 );
+                this->fixRefinementIntoWall( this->nx - 1, yIdx, zIdx, -1 );
             }
         }
     }
@@ -186,7 +187,7 @@ void GridImp::inital(const SPtr<Grid> fineGrid, uint numberOfLayers)
 #pragma omp parallel for
     for (int index = 0; index < (int)this->size; index++)
         this->findEndOfGridStopperNode(index);
-
+    
     *logging::out << logging::Logger::INFO_INTERMEDIATE
         << "Grid created: " << "from (" << this->startX << ", " << this->startY << ", " << this->startZ << ") to (" << this->endX << ", " << this->endY << ", " << this->endZ << ")\n"
         << "nodes: " << this->nx << " x " << this->ny << " x " << this->nz << " = " << this->size << "\n";
@@ -440,7 +441,7 @@ void GridImp::findEndOfGridStopperNode(uint index)
         else
             this->field.setFieldEntryToStopperOutOfGridBoundary(index);
     }
-
+    
 	if (isValidEndOfGridBoundaryStopper(index))
 		this->field.setFieldEntryToStopperOutOfGridBoundary(index);
 }
@@ -1167,7 +1168,7 @@ void GridImp::findInvalidBoundaryNodes(uint index)
 // --------------------------------------------------------- //
 void GridImp::mesh(Object* object)
 {
-    TriangularMesh* triangularMesh = dynamic_cast<TriangularMesh*>(object);
+    TriangularMesh *triangularMesh = dynamic_cast<TriangularMesh *>(object);
     if (triangularMesh)
         triangularMeshDiscretizationStrategy->discretize(triangularMesh, this, INVALID_SOLID, FLUID);
     else
@@ -1234,6 +1235,7 @@ void GridImp::closeNeedleCells()
     uint numberOfClosedNeedleCells = 0;
 
     do{
+        numberOfClosedNeedleCells = 0;
 #pragma omp parallel for reduction(+ : numberOfClosedNeedleCells)
         for (int index = 0; index < (int)this->size; index++) {
             if (this->closeCellIfNeedle(index))
@@ -1274,6 +1276,7 @@ void GridImp::closeNeedleCellsThinWall()
     uint numberOfClosedNeedleCells = 0;
 
     do{
+        numberOfClosedNeedleCells = 0;
 #pragma omp parallel for reduction(+ : numberOfClosedNeedleCells)
         for (int index = 0; index < (int)this->size; index++) {
             if (this->closeCellIfNeedleThinWall(index))
@@ -1457,7 +1460,6 @@ void GridImp::calculateQs(const uint index, const Vertex &point, Object* object)
                     
                 this->qPatches[ this->qIndices[index] ] = 0;
 
-				//printf("%d %f \n", this->qIndices[index], subdistance);
 			}
 		}
 	}
@@ -1657,7 +1659,7 @@ uint GridImp::getReceiveIndex(int direction, uint index)
     return this->communicationIndices[direction].receiveIndices[ index ];
 }
 
-void GridImp::repairCommunicationInices(int direction )
+void GridImp::repairCommunicationIndices(int direction)
 {
     this->communicationIndices[direction].sendIndices.insert( this->communicationIndices[direction].sendIndices.end(), 
                                                               this->communicationIndices[direction+1].sendIndices.begin(), 
@@ -1772,18 +1774,18 @@ real GridImp::getMaximumOnNodes(const real &maxExact, const real &decimalStart,
 }
 
 uint GridImp::getXIndex(real x) const 
-{
-    return std::lround((x - startX) / delta);
+{ 
+    return std::lround((x - startX) / delta); 
 }
 
 uint GridImp::getYIndex(real y) const
-{
-    return std::lround((y - startY) / delta);
+{ 
+    return std::lround((y - startY) / delta); 
 }
 
 uint GridImp::getZIndex(real z) const
-{
-	return std::lround((z - startZ) / delta);
+{ 
+    return std::lround((z - startZ) / delta); 
 }
 
 real GridImp::getDelta() const
@@ -1798,7 +1800,7 @@ uint GridImp::getSize() const
 
 uint GridImp::getSparseSize() const
 {
-    return this->sparseSize;
+    return this->sparseSize; 
 }
 
 Field GridImp::getField() const
@@ -1955,7 +1957,7 @@ void GridImp::getNodeValues(real *xCoords, real *yCoords, real *zCoords, uint *n
     geo[0] = GEOSOLID;
 
     int nodeNumber = 0;
-    for (uint i = 0; i < this->getSize(); i++)
+    for (uint i = 0; i < this->size; i++)
     {
         if (this->sparseIndices[i] == -1)
             continue;
@@ -1991,4 +1993,4 @@ void GridImp::print() const
            endX, endY, endZ, size, delta);
     if(this->gridInterface)
         this->gridInterface->print();
-}
\ No newline at end of file
+}
diff --git a/src/gpu/GridGenerator/grid/GridImp.h b/src/gpu/GridGenerator/grid/GridImp.h
index 6d6000b67d08da40349548afeb12028a0b265521..2101d5517e103fdd4fa07191cd8231bb3278d21f 100644
--- a/src/gpu/GridGenerator/grid/GridImp.h
+++ b/src/gpu/GridGenerator/grid/GridImp.h
@@ -37,12 +37,12 @@
 
 #include "Core/LbmOrGks.h"
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
-#include "grid/distributions/Distribution.h"
-#include "grid/Grid.h"
-#include "grid/Cell.h"
-#include "grid/Field.h" 
+#include "gpu/GridGenerator/grid/distributions/Distribution.h"
+#include "gpu/GridGenerator/grid/Grid.h"
+#include "gpu/GridGenerator/grid/Cell.h"
+#include "gpu/GridGenerator/grid/Field.h" 
 
 class TriangularMesh;
 struct Vertex;
@@ -70,7 +70,7 @@ extern int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
 class GRIDGENERATOR_EXPORT GridImp : public enableSharedFromThis<GridImp>, public Grid
 {
-private:
+protected:
     GridImp() = default;
     GridImp(Object* object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, Distribution d, uint level);
 
@@ -126,7 +126,7 @@ private:
 
     TriangularMeshDiscretizationStrategy *triangularMeshDiscretizationStrategy;
 
-    uint numberOfSolidBoundaryNodes;
+    uint numberOfSolidBoundaryNodes = 0;
 
     bool enableFixRefinementIntoTheWall;
 
@@ -209,7 +209,7 @@ public:
     bool isNode(uint index, char type) const;
     bool nodeInNextCellIs(int index, char type) const;
     bool hasAllNeighbors(uint index) const;
-    bool hasNeighborOfType(uint index, char type)const;
+    bool hasNeighborOfType(uint index, char type) const;
     bool cellContainsOnly(Cell &cell, char type) const;
     bool cellContainsOnly(Cell &cell, char typeA, char typeB) const;
 
@@ -246,6 +246,7 @@ public:
     uint getNumberOfNodesCF() const override;
     uint getNumberOfNodesFC() const override;
     void getGridInterfaceIndices(uint *iCellCfc, uint *iCellCff, uint *iCellFcc, uint *iCellFcf) const override;
+
     static void getGridInterface(uint *gridInterfaceList, const uint *oldGridInterfaceList, uint size);
 
     int *getNeighborsX() const override;
@@ -305,7 +306,11 @@ public:
     void findQsPrimitive(Object *object);
 
 private:
-    enum class qComputationStageType { FindSolidBoundaryNodes, ComputeQs } qComputationStage;
+
+    enum class qComputationStageType{
+        FindSolidBoundaryNodes,
+        ComputeQs
+    } qComputationStage;
 
 public:
     void enableFindSolidBoundaryNodes() override
@@ -336,7 +341,7 @@ public:
     uint getSendIndex(int direction, uint index) override;
     uint getReceiveIndex(int direction, uint index) override;
 
-    void repairCommunicationInices(int direction) override;
+    void repairCommunicationIndices(int direction) override;
 
 public:
     struct CommunicationIndices {
diff --git a/src/gpu/GridGenerator/grid/GridInterface.cpp b/src/gpu/GridGenerator/grid/GridInterface.cpp
index 47cb8ef9dd7c4704e420ca68888ce0d56c48a59e..9194f12824e2a95b4880647586eeba70be9984b1 100644
--- a/src/gpu/GridGenerator/grid/GridInterface.cpp
+++ b/src/gpu/GridGenerator/grid/GridInterface.cpp
@@ -40,6 +40,9 @@
 #include "grid/Field.h"
 #include "grid/NodeValues.h"
 
+#include "lbm/constants/D3Q27.h"
+
+using namespace vf::lbm;
 using namespace vf::gpu;
 
 GridInterface::GridInterface()
@@ -373,7 +376,7 @@ uint GridInterface::findOffsetCF(const uint& indexOnCoarseGrid, GridImp* coarseG
     Cell cell(x, y, z, coarseGrid->getDelta());
 
     if( coarseGrid->cellContainsOnly( cell, FLUID, FLUID_CFC ) ){
-        this->cf.offset[ interfaceIndex ] = DIR_27_ZERO;
+        this->cf.offset[ interfaceIndex ] = dir::REST;
         return indexOnCoarseGrid;
     }
 
@@ -408,7 +411,7 @@ uint GridInterface::findOffsetFC(const uint& indexOnFineGrid, GridImp* fineGrid,
     Cell cell(x, y, z, fineGrid->getDelta());
 
     if( fineGrid->cellContainsOnly( cell, FLUID, FLUID_FCF ) ){
-        this->fc.offset[ interfaceIndex ] = DIR_27_ZERO;
+        this->fc.offset[ interfaceIndex ] = dir::REST;
         return indexOnFineGrid;
     }
 
diff --git a/src/gpu/GridGenerator/grid/GridInterface.h b/src/gpu/GridGenerator/grid/GridInterface.h
index 303d79d4995ea04fe30b2a004c5738bf9c926cf2..b5f71317e7755a8b6bcfe3da084e0fc9155642f8 100644
--- a/src/gpu/GridGenerator/grid/GridInterface.h
+++ b/src/gpu/GridGenerator/grid/GridInterface.h
@@ -33,7 +33,7 @@
 #ifndef GRID_INTERFACE_H
 #define GRID_INTERFACE_H
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 class GridImp;
 
diff --git a/src/gpu/GridGenerator/grid/distributions/D3Q27.h b/src/gpu/GridGenerator/grid/distributions/D3Q27.h
index 680fa88305b793934747d09113f284bfe96b4988..4ef041a13678516f116c13c9b9996d6f378ef854 100644
--- a/src/gpu/GridGenerator/grid/distributions/D3Q27.h
+++ b/src/gpu/GridGenerator/grid/distributions/D3Q27.h
@@ -33,41 +33,6 @@
 #ifndef D3Q27_H_
 #define D3Q27_H_
 
-#define DIR_27_E    0
-#define DIR_27_W    1
-#define DIR_27_N    2
-#define DIR_27_S    3
-#define DIR_27_T    4
-#define DIR_27_B    5
-
-#define DIR_27_NE   6
-#define DIR_27_SW   7
-#define DIR_27_SE   8
-#define DIR_27_NW   9
-#define DIR_27_TE   10
-#define DIR_27_BW   11
-#define DIR_27_BE   12
-#define DIR_27_TW   13
-#define DIR_27_TN   14
-#define DIR_27_BS   15
-#define DIR_27_BN   16
-#define DIR_27_TS   17
-#define DIR_27_ZERO 18
-
-#define DIR_27_TNE  19
-#define DIR_27_BNE  20
-#define DIR_27_TSE  21
-#define DIR_27_BSE  22
-
-#define DIR_27_TNW  23
-#define DIR_27_BNW  24
-#define DIR_27_TSW  25
-#define DIR_27_BSW  26
-
-#define DIR_27_START  0
-#define DIR_27_END   26
-
-
 #define DIR_27_E_X  1
 #define DIR_27_E_Y  0
 #define DIR_27_E_Z  0
@@ -159,7 +124,6 @@
 #define DIR_27_BSE_Y  -1
 #define DIR_27_BSE_Z  -1
 
-
 #define DIR_27_TNW_X  -1
 #define DIR_27_TNW_Y  1
 #define DIR_27_TNW_Z  1
@@ -176,4 +140,8 @@
 #define DIR_27_BSW_Y  -1
 #define DIR_27_BSW_Z  -1
 
+#define DIR_27_REST_X  0
+#define DIR_27_REST_Y  0
+#define DIR_27_REST_Z  0
+
 #endif
diff --git a/src/gpu/GridGenerator/grid/distributions/Distribution.cpp b/src/gpu/GridGenerator/grid/distributions/Distribution.cpp
index b0200812631aeff1947a56f78cae4232bd4d3ee7..8192c114413dfdf32492717b57870cadd35130cb 100644
--- a/src/gpu/GridGenerator/grid/distributions/Distribution.cpp
+++ b/src/gpu/GridGenerator/grid/distributions/Distribution.cpp
@@ -35,168 +35,162 @@
 #include <stdio.h>
 
 #include "grid/distributions/D3Q27.h"
-
+#include "lbm/constants/D3Q27.h"
 #include "grid/Grid.h"
+using namespace vf::lbm::dir;
 
 Distribution DistributionHelper::getDistribution27() 
 {
     Distribution d27;
     d27.name = "D3Q27";
-    d27.dir_start = DIR_27_START;
-    d27.dir_end = DIR_27_END;
-
-    d27.dirs = new int[(DIR_27_END + 1) * DIMENSION];
-
-    d27.directions = new Direction[DIR_27_END + 1];
-    d27.directions[0] = Direction(DIR_27_E_X, DIR_27_E_Y, DIR_27_E_Z);
-    d27.directions[1] = Direction(DIR_27_W_X, DIR_27_W_Y, DIR_27_W_Z);
-    d27.directions[2] = Direction(DIR_27_N_X, DIR_27_N_Y, DIR_27_N_Z);
-    d27.directions[3] = Direction(DIR_27_S_X, DIR_27_S_Y, DIR_27_S_Z);
-
-    d27.directions[4] = Direction(DIR_27_T_X, DIR_27_T_Y, DIR_27_T_Z);
-    d27.directions[5] = Direction(DIR_27_B_X, DIR_27_B_Y, DIR_27_B_Z);
-
-    d27.directions[6] = Direction(DIR_27_NE_X, DIR_27_NE_Y, DIR_27_NE_Z);
-    d27.directions[7] = Direction(DIR_27_SW_X, DIR_27_SW_Y, DIR_27_SW_Z);
-    d27.directions[8] = Direction(DIR_27_SE_X, DIR_27_SE_Y, DIR_27_SE_Z);
-    d27.directions[9] = Direction(DIR_27_NW_X, DIR_27_NW_Y, DIR_27_NW_Z);
-
-    d27.directions[10] = Direction(DIR_27_TE_X, DIR_27_TE_Y, DIR_27_TE_Z);
-    d27.directions[11] = Direction(DIR_27_BW_X, DIR_27_BW_Y, DIR_27_BW_Z);
-    d27.directions[12] = Direction(DIR_27_BE_X, DIR_27_BE_Y, DIR_27_BE_Z);
-    d27.directions[13] = Direction(DIR_27_TW_X, DIR_27_TW_Y, DIR_27_TW_Z);
-
-    d27.directions[14] = Direction(DIR_27_TN_X, DIR_27_TN_Y, DIR_27_TN_Z);
-    d27.directions[15] = Direction(DIR_27_BS_X, DIR_27_BS_Y, DIR_27_BS_Z);
-    d27.directions[16] = Direction(DIR_27_BN_X, DIR_27_BN_Y, DIR_27_BN_Z);
-    d27.directions[17] = Direction(DIR_27_TS_X, DIR_27_TS_Y, DIR_27_TS_Z);
-
-    d27.directions[18] = Direction(0, 0, 0);
-
-    d27.directions[19] = Direction(DIR_27_TNE_X, DIR_27_TNE_Y, DIR_27_TNE_Z);
-    d27.directions[20] = Direction(DIR_27_BNE_X, DIR_27_BNE_Y, DIR_27_BNE_Z);
-
-    d27.directions[21] = Direction(DIR_27_TSE_X, DIR_27_TSE_Y, DIR_27_TSE_Z);
-    d27.directions[22] = Direction(DIR_27_BSE_X, DIR_27_BSE_Y, DIR_27_BSE_Z);
+    d27.dir_start = STARTDIR;
+    d27.dir_end = ENDDIR;
+
+    d27.dirs = new int[(ENDDIR + 1) * DIMENSION];
+
+    d27.directions = new Direction[ENDDIR + 1];
+    d27.directions[E] = Direction(DIR_27_E_X, DIR_27_E_Y, DIR_27_E_Z);
+    d27.directions[W] = Direction(DIR_27_W_X, DIR_27_W_Y, DIR_27_W_Z);
+    d27.directions[N] = Direction(DIR_27_N_X, DIR_27_N_Y, DIR_27_N_Z);
+    d27.directions[S] = Direction(DIR_27_S_X, DIR_27_S_Y, DIR_27_S_Z);
+    d27.directions[T] = Direction(DIR_27_T_X, DIR_27_T_Y, DIR_27_T_Z);
+    d27.directions[B] = Direction(DIR_27_B_X, DIR_27_B_Y, DIR_27_B_Z);
+
+    d27.directions[NE] = Direction(DIR_27_NE_X, DIR_27_NE_Y, DIR_27_NE_Z);
+    d27.directions[SW] = Direction(DIR_27_SW_X, DIR_27_SW_Y, DIR_27_SW_Z);
+    d27.directions[SE] = Direction(DIR_27_SE_X, DIR_27_SE_Y, DIR_27_SE_Z);
+    d27.directions[NW] = Direction(DIR_27_NW_X, DIR_27_NW_Y, DIR_27_NW_Z);
+
+    d27.directions[TE] = Direction(DIR_27_TE_X, DIR_27_TE_Y, DIR_27_TE_Z);
+    d27.directions[BW] = Direction(DIR_27_BW_X, DIR_27_BW_Y, DIR_27_BW_Z);
+    d27.directions[BE] = Direction(DIR_27_BE_X, DIR_27_BE_Y, DIR_27_BE_Z);
+    d27.directions[TW] = Direction(DIR_27_TW_X, DIR_27_TW_Y, DIR_27_TW_Z);
+
+    d27.directions[TN] = Direction(DIR_27_TN_X, DIR_27_TN_Y, DIR_27_TN_Z);
+    d27.directions[BS] = Direction(DIR_27_BS_X, DIR_27_BS_Y, DIR_27_BS_Z);
+    d27.directions[BN] = Direction(DIR_27_BN_X, DIR_27_BN_Y, DIR_27_BN_Z);
+    d27.directions[TS] = Direction(DIR_27_TS_X, DIR_27_TS_Y, DIR_27_TS_Z);
+
+    d27.directions[REST] = Direction(DIR_27_REST_X, DIR_27_REST_Y, DIR_27_REST_Z);
+
+    d27.directions[TNE] = Direction(DIR_27_TNE_X, DIR_27_TNE_Y, DIR_27_TNE_Z);
+    d27.directions[TNW] = Direction(DIR_27_TNW_X, DIR_27_TNW_Y, DIR_27_TNW_Z);
+    d27.directions[TSE] = Direction(DIR_27_TSE_X, DIR_27_TSE_Y, DIR_27_TSE_Z);
+    d27.directions[TSW] = Direction(DIR_27_TSW_X, DIR_27_TSW_Y, DIR_27_TSW_Z);
+
+    d27.directions[BNE] = Direction(DIR_27_BNE_X, DIR_27_BNE_Y, DIR_27_BNE_Z);
+    d27.directions[BNW] = Direction(DIR_27_BNW_X, DIR_27_BNW_Y, DIR_27_BNW_Z);
+    d27.directions[BSE] = Direction(DIR_27_BSE_X, DIR_27_BSE_Y, DIR_27_BSE_Z);
+    d27.directions[BSW] = Direction(DIR_27_BSW_X, DIR_27_BSW_Y, DIR_27_BSW_Z);
+
+
+    d27.dirs[E * 3    ] = DIR_27_E_X;
+    d27.dirs[E * 3 + 1] = DIR_27_E_Y;
+    d27.dirs[E * 3 + 2] = DIR_27_E_Z;
+
+    d27.dirs[W * 3    ] = DIR_27_W_X;
+    d27.dirs[W * 3 + 1] = DIR_27_W_Y;
+    d27.dirs[W * 3 + 2] = DIR_27_W_Z;
+    
+    d27.dirs[N * 3    ] = DIR_27_N_X;
+    d27.dirs[N * 3 + 1] = DIR_27_N_Y;
+    d27.dirs[N * 3 + 2] = DIR_27_N_Z;
 
-    d27.directions[23] = Direction(DIR_27_TNW_X, DIR_27_TNW_Y, DIR_27_TNW_Z);
-    d27.directions[24] = Direction(DIR_27_BNW_X, DIR_27_BNW_Y, DIR_27_BNW_Z);
+    d27.dirs[S * 3    ] = DIR_27_S_X;
+    d27.dirs[S * 3 + 1] = DIR_27_S_Y;
+    d27.dirs[S * 3 + 2] = DIR_27_S_Z;
+    
+    d27.dirs[T * 3    ] = DIR_27_T_X;
+    d27.dirs[T * 3 + 1] = DIR_27_T_Y;
+    d27.dirs[T * 3 + 2] = DIR_27_T_Z;
+    
+    d27.dirs[B * 3    ] = DIR_27_B_X;
+    d27.dirs[B * 3 + 1] = DIR_27_B_Y;
+    d27.dirs[B * 3 + 2] = DIR_27_B_Z;
 
-    d27.directions[25] = Direction(DIR_27_TSW_X, DIR_27_TSW_Y, DIR_27_TSW_Z);
-    d27.directions[26] = Direction(DIR_27_BSW_X, DIR_27_BSW_Y, DIR_27_BSW_Z);
+    d27.dirs[NE * 3    ] = DIR_27_NE_X;
+    d27.dirs[NE * 3 + 1] = DIR_27_NE_Y;
+    d27.dirs[NE * 3 + 2] = DIR_27_NE_Z;
+    
+    d27.dirs[SW * 3    ] = DIR_27_SW_X;
+    d27.dirs[SW * 3 + 1] = DIR_27_SW_Y;
+    d27.dirs[SW * 3 + 2] = DIR_27_SW_Z;
 
+    d27.dirs[SE * 3    ] = DIR_27_SE_X;
+    d27.dirs[SE * 3 + 1] = DIR_27_SE_Y;
+    d27.dirs[SE * 3 + 2] = DIR_27_SE_Z;
 
-    int dir_num = 0;
-    d27.dirs[dir_num++] = DIR_27_E_X;
-    d27.dirs[dir_num++] = DIR_27_E_Y;
-    d27.dirs[dir_num++] = DIR_27_E_Z;
+    d27.dirs[NW * 3    ] = DIR_27_NW_X;
+    d27.dirs[NW * 3 + 1] = DIR_27_NW_Y;
+    d27.dirs[NW * 3 + 2] = DIR_27_NW_Z;
 
-    d27.dirs[dir_num++] = DIR_27_W_X;
-    d27.dirs[dir_num++] = DIR_27_W_Y;
-    d27.dirs[dir_num++] = DIR_27_W_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_N_X;
-    d27.dirs[dir_num++] = DIR_27_N_Y;
-    d27.dirs[dir_num++] = DIR_27_N_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_S_X;
-    d27.dirs[dir_num++] = DIR_27_S_Y;
-    d27.dirs[dir_num++] = DIR_27_S_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_T_X;
-    d27.dirs[dir_num++] = DIR_27_T_Y;
-    d27.dirs[dir_num++] = DIR_27_T_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_B_X;
-    d27.dirs[dir_num++] = DIR_27_B_Y;
-    d27.dirs[dir_num++] = DIR_27_B_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_NE_X;
-    d27.dirs[dir_num++] = DIR_27_NE_Y;
-    d27.dirs[dir_num++] = DIR_27_NE_Z;
-    
-    d27.dirs[dir_num++] = DIR_27_SW_X;
-    d27.dirs[dir_num++] = DIR_27_SW_Y;
-    d27.dirs[dir_num++] = DIR_27_SW_Z;
+    d27.dirs[TE * 3    ] = DIR_27_TE_X;
+    d27.dirs[TE * 3 + 1] = DIR_27_TE_Y;
+    d27.dirs[TE * 3 + 2] = DIR_27_TE_Z;
 
-    d27.dirs[dir_num++] = DIR_27_SE_X;
-    d27.dirs[dir_num++] = DIR_27_SE_Y;
-    d27.dirs[dir_num++] = DIR_27_SE_Z;
+    d27.dirs[BW * 3    ] = DIR_27_BW_X;
+    d27.dirs[BW * 3 + 1] = DIR_27_BW_Y;
+    d27.dirs[BW * 3 + 2] = DIR_27_BW_Z;
                               
-    d27.dirs[dir_num++] = DIR_27_NW_X;
-    d27.dirs[dir_num++] = DIR_27_NW_Y;
-    d27.dirs[dir_num++] = DIR_27_NW_Z;
+    d27.dirs[BE * 3    ] = DIR_27_BE_X;
+    d27.dirs[BE * 3 + 1] = DIR_27_BE_Y;
+    d27.dirs[BE * 3 + 2] = DIR_27_BE_Z;
                               
-    d27.dirs[dir_num++] = DIR_27_TE_X;
-    d27.dirs[dir_num++] = DIR_27_TE_Y;
-    d27.dirs[dir_num++] = DIR_27_TE_Z;
+    d27.dirs[TW * 3    ] = DIR_27_TW_X;
+    d27.dirs[TW * 3 + 1] = DIR_27_TW_Y;
+    d27.dirs[TW * 3 + 2] = DIR_27_TW_Z;
                               
-    d27.dirs[dir_num++] = DIR_27_BW_X;
-    d27.dirs[dir_num++] = DIR_27_BW_Y;
-    d27.dirs[dir_num++] = DIR_27_BW_Z;
+    d27.dirs[TN * 3    ] = DIR_27_TN_X;
+    d27.dirs[TN * 3 + 1] = DIR_27_TN_Y;
+    d27.dirs[TN * 3 + 2] = DIR_27_TN_Z;
                               
-    d27.dirs[dir_num++] = DIR_27_BE_X;
-    d27.dirs[dir_num++] = DIR_27_BE_Y;
-    d27.dirs[dir_num++] = DIR_27_BE_Z;
+    d27.dirs[BS * 3    ] = DIR_27_BS_X;
+    d27.dirs[BS * 3 + 1] = DIR_27_BS_Y;
+    d27.dirs[BS * 3 + 2] = DIR_27_BS_Z;
                               
-    d27.dirs[dir_num++] = DIR_27_TW_X;
-    d27.dirs[dir_num++] = DIR_27_TW_Y;
-    d27.dirs[dir_num++] = DIR_27_TW_Z;
-                              
-    d27.dirs[dir_num++] = DIR_27_TN_X;
-    d27.dirs[dir_num++] = DIR_27_TN_Y;
-    d27.dirs[dir_num++] = DIR_27_TN_Z;
-                              
-    d27.dirs[dir_num++] = DIR_27_BS_X;
-    d27.dirs[dir_num++] = DIR_27_BS_Y;
-    d27.dirs[dir_num++] = DIR_27_BS_Z;
-                              
-    d27.dirs[dir_num++] = DIR_27_BN_X;
-    d27.dirs[dir_num++] = DIR_27_BN_Y;
-    d27.dirs[dir_num++] = DIR_27_BN_Z;
-
-    d27.dirs[dir_num++] = DIR_27_TS_X;
-    d27.dirs[dir_num++] = DIR_27_TS_Y;
-    d27.dirs[dir_num++] = DIR_27_TS_Z;
-
-
-    d27.dirs[dir_num++] = 0;   //
-    d27.dirs[dir_num++] = 0;   //  ZERO ELEMENT
-    d27.dirs[dir_num++] = 0;   //
+    d27.dirs[BN * 3    ] = DIR_27_BN_X;
+    d27.dirs[BN * 3 + 1] = DIR_27_BN_Y;
+    d27.dirs[BN * 3 + 2] = DIR_27_BN_Z;
 
+    d27.dirs[TS * 3    ] = DIR_27_TS_X;
+    d27.dirs[TS * 3 + 1] = DIR_27_TS_Y;
+    d27.dirs[TS * 3 + 2] = DIR_27_TS_Z;
 
-    d27.dirs[dir_num++] = DIR_27_TNE_X;
-    d27.dirs[dir_num++] = DIR_27_TNE_Y;
-    d27.dirs[dir_num++] = DIR_27_TNE_Z;
+    d27.dirs[REST * 3    ] = DIR_27_REST_X;   //
+    d27.dirs[REST * 3 + 1] = DIR_27_REST_Y;   //  ZERO ELEMENT
+    d27.dirs[REST * 3 + 2] = DIR_27_REST_Z;   //
 
-    d27.dirs[dir_num++] = DIR_27_BNE_X;
-    d27.dirs[dir_num++] = DIR_27_BNE_Y;
-    d27.dirs[dir_num++] = DIR_27_BNE_Z;
+    d27.dirs[TNE * 3    ] = DIR_27_TNE_X;
+    d27.dirs[TNE * 3 + 1] = DIR_27_TNE_Y;
+    d27.dirs[TNE * 3 + 2] = DIR_27_TNE_Z;
 
-    d27.dirs[dir_num++] = DIR_27_TSE_X;
-    d27.dirs[dir_num++] = DIR_27_TSE_Y;
-    d27.dirs[dir_num++] = DIR_27_TSE_Z;
+    d27.dirs[BNE * 3    ] = DIR_27_BNE_X;
+    d27.dirs[BNE * 3 + 1] = DIR_27_BNE_Y;
+    d27.dirs[BNE * 3 + 2] = DIR_27_BNE_Z;
 
-    d27.dirs[dir_num++] = DIR_27_BSE_X;
-    d27.dirs[dir_num++] = DIR_27_BSE_Y;
-    d27.dirs[dir_num++] = DIR_27_BSE_Z;
+    d27.dirs[TSE * 3    ] = DIR_27_TSE_X;
+    d27.dirs[TSE * 3 + 1] = DIR_27_TSE_Y;
+    d27.dirs[TSE * 3 + 2] = DIR_27_TSE_Z;
 
+    d27.dirs[BSE * 3    ] = DIR_27_BSE_X;
+    d27.dirs[BSE * 3 + 1] = DIR_27_BSE_Y;
+    d27.dirs[BSE * 3 + 2] = DIR_27_BSE_Z;
 
-    d27.dirs[dir_num++] = DIR_27_TNW_X;
-    d27.dirs[dir_num++] = DIR_27_TNW_Y;
-    d27.dirs[dir_num++] = DIR_27_TNW_Z;
+    d27.dirs[TNW * 3    ] = DIR_27_TNW_X;
+    d27.dirs[TNW * 3 + 1] = DIR_27_TNW_Y;
+    d27.dirs[TNW * 3 + 2] = DIR_27_TNW_Z;
 
-    d27.dirs[dir_num++] = DIR_27_BNW_X;
-    d27.dirs[dir_num++] = DIR_27_BNW_Y;
-    d27.dirs[dir_num++] = DIR_27_BNW_Z;
+    d27.dirs[BNW * 3    ] = DIR_27_BNW_X;
+    d27.dirs[BNW * 3 + 1] = DIR_27_BNW_Y;
+    d27.dirs[BNW * 3 + 2] = DIR_27_BNW_Z;
 
-    d27.dirs[dir_num++] = DIR_27_TSW_X;
-    d27.dirs[dir_num++] = DIR_27_TSW_Y;
-    d27.dirs[dir_num++] = DIR_27_TSW_Z;
+    d27.dirs[TSW * 3    ] = DIR_27_TSW_X;
+    d27.dirs[TSW * 3 + 1] = DIR_27_TSW_Y;
+    d27.dirs[TSW * 3 + 2] = DIR_27_TSW_Z;
 
-    d27.dirs[dir_num++] = DIR_27_BSW_X;
-    d27.dirs[dir_num++] = DIR_27_BSW_Y;
-    d27.dirs[dir_num++] = DIR_27_BSW_Z;
+    d27.dirs[BSW * 3    ] = DIR_27_BSW_X;
+    d27.dirs[BSW * 3 + 1] = DIR_27_BSW_Y;
+    d27.dirs[BSW * 3 + 2] = DIR_27_BSW_Z;
 
     return d27;
 }
diff --git a/src/gpu/GridGenerator/grid/distributions/Distribution.h b/src/gpu/GridGenerator/grid/distributions/Distribution.h
index abc6d8105c9daeb83f4e31478a55942f48bf5e65..7982abc235b020003526b10c885f4936bf661936 100644
--- a/src/gpu/GridGenerator/grid/distributions/Distribution.h
+++ b/src/gpu/GridGenerator/grid/distributions/Distribution.h
@@ -36,7 +36,7 @@
 #include <vector>
 #include <string>
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 #define DIR_END_MAX 27
 
diff --git a/src/gpu/GridGenerator/grid/distributions/DistributionTest.cpp b/src/gpu/GridGenerator/grid/distributions/DistributionTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86b2f3b5139482d2be92788ea646cea1069a6052
--- /dev/null
+++ b/src/gpu/GridGenerator/grid/distributions/DistributionTest.cpp
@@ -0,0 +1,61 @@
+# include <gmock/gmock.h>
+#include <string>
+# include "Distribution.h"
+
+#include "grid/distributions/D3Q27.h"
+#include "lbm/constants/D3Q27.h"
+using namespace vf::lbm::dir;
+
+TEST(DistributionTest, DistributionReturnsCorrectDirections)
+{
+    Distribution dist = DistributionHelper::getDistribution27();
+
+    EXPECT_THAT(dist.directions[E][0], testing::Eq(DIR_27_E_X));
+    EXPECT_THAT(dist.directions[E][1], testing::Eq(DIR_27_E_Y));
+    EXPECT_THAT(dist.directions[E][2], testing::Eq(DIR_27_E_Z));
+    EXPECT_THAT(dist.dirs[E * 3    ], testing::Eq(DIR_27_E_X));
+    EXPECT_THAT(dist.dirs[E * 3 + 1], testing::Eq(DIR_27_E_Y));
+    EXPECT_THAT(dist.dirs[E * 3 + 2], testing::Eq(DIR_27_E_Z));
+
+    EXPECT_THAT(dist.directions[B][0], testing::Eq(DIR_27_B_X));
+    EXPECT_THAT(dist.directions[B][1], testing::Eq(DIR_27_B_Y));
+    EXPECT_THAT(dist.directions[B][2], testing::Eq(DIR_27_B_Z));
+    EXPECT_THAT(dist.dirs[B * 3    ], testing::Eq(DIR_27_B_X));
+    EXPECT_THAT(dist.dirs[B * 3 + 1], testing::Eq(DIR_27_B_Y));
+    EXPECT_THAT(dist.dirs[B * 3 + 2], testing::Eq(DIR_27_B_Z));
+    
+    EXPECT_THAT(dist.directions[REST][0], testing::Eq(0));
+    EXPECT_THAT(dist.directions[REST][1], testing::Eq(0));
+    EXPECT_THAT(dist.directions[REST][2], testing::Eq(0));
+    EXPECT_THAT(dist.dirs[REST * 3    ], testing::Eq(0));
+    EXPECT_THAT(dist.dirs[REST * 3 + 1], testing::Eq(0));
+    EXPECT_THAT(dist.dirs[REST * 3 + 2], testing::Eq(0));
+
+    EXPECT_THAT(dist.directions[NE][0], testing::Eq(DIR_27_NE_X));
+    EXPECT_THAT(dist.directions[NE][1], testing::Eq(DIR_27_NE_Y));
+    EXPECT_THAT(dist.directions[NE][2], testing::Eq(DIR_27_NE_Z));
+    EXPECT_THAT(dist.dirs[NE * 3    ], testing::Eq(DIR_27_NE_X));
+    EXPECT_THAT(dist.dirs[NE * 3 + 1], testing::Eq(DIR_27_NE_Y));
+    EXPECT_THAT(dist.dirs[NE * 3 + 2], testing::Eq(DIR_27_NE_Z));
+
+    EXPECT_THAT(dist.directions[TS][0], testing::Eq(DIR_27_TS_X));
+    EXPECT_THAT(dist.directions[TS][1], testing::Eq(DIR_27_TS_Y));
+    EXPECT_THAT(dist.directions[TS][2], testing::Eq(DIR_27_TS_Z));
+    EXPECT_THAT(dist.dirs[TS * 3    ], testing::Eq(DIR_27_TS_X));
+    EXPECT_THAT(dist.dirs[TS * 3 + 1], testing::Eq(DIR_27_TS_Y));
+    EXPECT_THAT(dist.dirs[TS * 3 + 2], testing::Eq(DIR_27_TS_Z));
+
+    EXPECT_THAT(dist.directions[TNE][0], testing::Eq(DIR_27_TNE_X));
+    EXPECT_THAT(dist.directions[TNE][1], testing::Eq(DIR_27_TNE_Y));
+    EXPECT_THAT(dist.directions[TNE][2], testing::Eq(DIR_27_TNE_Z));
+    EXPECT_THAT(dist.dirs[TNE * 3    ], testing::Eq(DIR_27_TNE_X));
+    EXPECT_THAT(dist.dirs[TNE * 3 + 1], testing::Eq(DIR_27_TNE_Y));
+    EXPECT_THAT(dist.dirs[TNE * 3 + 2], testing::Eq(DIR_27_TNE_Z));
+
+    EXPECT_THAT(dist.directions[BSW][0], testing::Eq(DIR_27_BSW_X));
+    EXPECT_THAT(dist.directions[BSW][1], testing::Eq(DIR_27_BSW_Y));
+    EXPECT_THAT(dist.directions[BSW][2], testing::Eq(DIR_27_BSW_Z));
+    EXPECT_THAT(dist.dirs[BSW * 3    ], testing::Eq(DIR_27_BSW_X));
+    EXPECT_THAT(dist.dirs[BSW * 3 + 1], testing::Eq(DIR_27_BSW_Y));
+    EXPECT_THAT(dist.dirs[BSW * 3 + 2], testing::Eq(DIR_27_BSW_Z));
+}
\ No newline at end of file
diff --git a/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp b/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
index 173f79c184c0a455ffd5b27cae59e07fa6dd4fa6..d3eb221265b2f8c79d5aece8729585733c2d60e8 100644
--- a/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
+++ b/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
@@ -118,7 +118,7 @@ std::vector<Triangle> STLReader::readASCIISTLWithPatches(const std::string& name
     std::ifstream file;
     file.open(name.c_str(), std::ifstream::in);
 
-    if( !file.is_open() ) throw std::runtime_error(name + "cannot be opened!");
+    if( !file.is_open() ) throw std::runtime_error(name + " cannot be opened!");
 
     uint currentPatchIndex = 0;
 
diff --git a/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h b/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
index d5d2a377b33697704b86f8b78987fd0af75be415..4a4552f74b69949865e233014d74ac7168b36b31 100644
--- a/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
+++ b/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h
@@ -42,7 +42,7 @@
 
 #include "Core/NonCreatable.h"
 
-#include "global.h"
+#include "gpu/GridGenerator/global.h"
 
 class UnstructuredGridBuilder;
 class GridBuilder;
diff --git a/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.cpp b/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c684dfe13a4b99477c317dd6cf00ccef90cc9eec
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.cpp
@@ -0,0 +1,108 @@
+#include "BoundaryConditionFactory.h"
+#include "GPU/GPU_Interface.h"
+#include "Parameter/Parameter.h"
+#include "grid/BoundaryConditions/BoundaryCondition.h"
+#include <variant>
+
+void BoundaryConditionFactory::setVelocityBoundaryCondition(VelocityBC boundaryConditionType)
+{
+    this->velocityBoundaryCondition = boundaryConditionType;
+}
+
+void BoundaryConditionFactory::setNoSlipBoundaryCondition(const NoSlipBC boundaryConditionType)
+{
+    this->noSlipBoundaryCondition = boundaryConditionType;
+}
+
+void BoundaryConditionFactory::setSlipBoundaryCondition(const SlipBC boundaryConditionType)
+{
+    this->slipBoundaryCondition = boundaryConditionType;
+}
+
+void BoundaryConditionFactory::setPressureBoundaryCondition(const PressureBC boundaryConditionType)
+{
+    this->pressureBoundaryCondition = boundaryConditionType;
+}
+
+void BoundaryConditionFactory::setGeometryBoundaryCondition(
+    const std::variant<VelocityBC, NoSlipBC, SlipBC> boundaryConditionType)
+{
+    this->geometryBoundaryCondition = boundaryConditionType;
+}
+
+boundaryCondition BoundaryConditionFactory::getVelocityBoundaryConditionPost(bool isGeometryBC) const
+{
+    const VelocityBC &boundaryCondition =
+        isGeometryBC ? std::get<VelocityBC>(this->geometryBoundaryCondition) : this->velocityBoundaryCondition;
+
+    // for descriptions of the boundary conditions refer to the header
+    switch (boundaryCondition) {
+        case VelocityBC::VelocitySimpleBounceBackCompressible:
+            return QVelDevPlainBB27;
+            break;
+        case VelocityBC::VelocityCompressible:
+            return QVelDevComp27;
+            break;
+        default:
+            return nullptr;
+    }
+}
+
+boundaryCondition BoundaryConditionFactory::getNoSlipBoundaryConditionPost(bool isGeometryBC) const
+{
+    const NoSlipBC &boundaryCondition =
+        isGeometryBC ? std::get<NoSlipBC>(this->geometryBoundaryCondition) : this->noSlipBoundaryCondition;
+
+    // for descriptions of the boundary conditions refer to the header
+    switch (boundaryCondition) {
+        case NoSlipBC::NoSlipImplicitBounceBack:
+            return [](ParameterStruct *, QforBoundaryConditions *) {};
+            break;
+        case NoSlipBC::NoSlipBounceBack:
+            return BBDev27;
+            break;
+        case NoSlipBC::NoSlipCompressible:
+            return QDevComp27;
+            break;
+        default:
+            return nullptr;
+    }
+}
+
+boundaryCondition BoundaryConditionFactory::getSlipBoundaryConditionPost(bool isGeometryBC) const
+{
+    const SlipBC &boundaryCondition =
+        isGeometryBC ? std::get<SlipBC>(this->geometryBoundaryCondition) : this->slipBoundaryCondition;
+
+    // for descriptions of the boundary conditions refer to the header
+    switch (boundaryCondition) {
+        case SlipBC::SlipCompressible:
+            return QSlipDevComp27;
+            break;
+        default:
+            return nullptr;
+    }
+}
+
+boundaryCondition BoundaryConditionFactory::getPressureBoundaryConditionPre() const
+{
+    // for descriptions of the boundary conditions refer to the header
+    switch (this->pressureBoundaryCondition) {
+        case PressureBC::PressureNonEquilibriumCompressible:
+            return QPressDevNEQ27;
+            break;
+        default:
+            return nullptr;
+    }
+}
+
+boundaryCondition BoundaryConditionFactory::getGeometryBoundaryConditionPost() const
+{
+    if (std::holds_alternative<VelocityBC>(this->geometryBoundaryCondition))
+        return this->getVelocityBoundaryConditionPost(true);
+    else if (std::holds_alternative<NoSlipBC>(this->geometryBoundaryCondition))
+        return this->getNoSlipBoundaryConditionPost(true);
+    else if (std::holds_alternative<SlipBC>(this->geometryBoundaryCondition))
+        return this->getSlipBoundaryConditionPost(true);
+    return nullptr;
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h b/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..97618f2f5a519123e0a2ca031926ba8d47d58d1a
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/BoundaryConditions/BoundaryConditionFactory.h
@@ -0,0 +1,79 @@
+#ifndef BC_FACTORY
+#define BC_FACTORY
+
+#include <functional>
+#include <map>
+#include <string>
+#include <variant>
+
+#include "LBM/LB.h"
+#include "Parameter/Parameter.h"
+#include "grid/BoundaryConditions/Side.h"
+
+struct ParameterStruct;
+class Parameter;
+
+using boundaryCondition = std::function<void(ParameterStruct *, QforBoundaryConditions *)>;
+using boundaryConditionPara = std::function<void(Parameter *, QforBoundaryConditions *, const int level)>;
+
+class BoundaryConditionFactory
+{
+public:
+    //! \brief An enumeration for selecting a velocity boundary condition
+    enum class VelocityBC {
+        //! - VelocitySimpleBounceBackCompressible = plain bounce back velocity boundary condition
+        VelocitySimpleBounceBackCompressible,
+        //! - VelocityCompressible = interpolated velocity boundary condition, based on subgrid distances
+        VelocityCompressible,
+    };
+
+    //! \brief An enumeration for selecting a no-slip boundary condition
+    enum class NoSlipBC {
+        //! - NoSlipImplicitBounceBack = implicit bounce back by Esoteric Twist
+        NoSlipImplicitBounceBack,
+        //! - NoSlipBounceBack = bounce back no-slip boundary condition
+        NoSlipBounceBack,
+        //! - NoSlipCompressible = interpolated no-slip boundary condition, based on subgrid distances
+        NoSlipCompressible,
+    };
+
+    //! \brief An enumeration for selecting a slip boundary condition
+    enum class SlipBC {
+        //! - SlipCompressible = interpolated slip boundary condition, based on subgrid distances
+        SlipCompressible,
+    };
+
+    //! \brief An enumeration for selecting a pressure boundary condition
+    enum class PressureBC {
+        //! - PressureNonEquilibriumCompressible = pressure boundary condition based on non-equilibrium
+        PressureNonEquilibriumCompressible,
+    };
+
+    void setVelocityBoundaryCondition(const BoundaryConditionFactory::VelocityBC boundaryConditionType);
+    void setNoSlipBoundaryCondition(const BoundaryConditionFactory::NoSlipBC boundaryConditionType);
+    void setSlipBoundaryCondition(const BoundaryConditionFactory::SlipBC boundaryConditionType);
+    void setPressureBoundaryCondition(const BoundaryConditionFactory::PressureBC boundaryConditionType);
+
+    //!param boundaryConditionType: a velocity, no-slip or slip boundary condition
+    //! \details suggestions for boundaryConditionType:
+    //!
+    //! - velocity: VelocityCompressible
+    //!
+    //! - no-slip:  NoSlipBounceBack, NoSlipCompressible
+    void setGeometryBoundaryCondition(const std::variant<VelocityBC, NoSlipBC, SlipBC> boundaryConditionType);
+
+    boundaryCondition getVelocityBoundaryConditionPost(bool isGeometryBC = false) const;
+    boundaryCondition getNoSlipBoundaryConditionPost(bool isGeometryBC = false) const;
+    boundaryCondition getSlipBoundaryConditionPost(bool isGeometryBC = false) const;
+    boundaryCondition getPressureBoundaryConditionPre() const;
+    boundaryCondition getGeometryBoundaryConditionPost() const;
+
+private:
+    VelocityBC velocityBoundaryCondition;
+    NoSlipBC noSlipBoundaryCondition = NoSlipBC::NoSlipImplicitBounceBack;
+    SlipBC slipBoundaryCondition;
+    PressureBC pressureBoundaryCondition;
+    std::variant<VelocityBC, NoSlipBC, SlipBC> geometryBoundaryCondition  = NoSlipBC::NoSlipImplicitBounceBack;
+};
+
+#endif
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
index 48fe29321f5f884a2e73118bab1ea352fcf5f6ec..6bf31bdc1be6f4cbce0c156246ca348d3e8692a4 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
@@ -80,8 +80,8 @@ void GridProvider::setInitalNodeValues(const int numberOfNodes) const
 
 void GridProvider::setVelocitySize(int size) const
 {
-    para->getParH()->numberOfVeloBCnodes = size;
-    para->getParD()->numberOfVeloBCnodes = size;
+    para->getParH()->velocityBC.numberOfBCnodes = size;
+    para->getParD()->velocityBC.numberOfBCnodes = size;
 }
 
 void GridProvider::allocAndCopyForcing()
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
index a68e8543f8673329f51be9de97d108e6eba4233f..6c1c0e2b0ef81a21ca3e268a209a771e616eca18 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
@@ -36,11 +36,13 @@
 
 #include "GPU/CudaMemoryManager.h"
 #include "GridGenerator/grid/GridBuilder/GridBuilder.h"
-#include "LBM/D3Q27.h"
 #include "LBM/LB.h"
 #include "Parameter/Parameter.h"
 #include "utilities/math/Math.h"
 
+#include "lbm/constants/D3Q27.h"
+using namespace vf::lbm::dir;
+
 GridGenerator::GridGenerator(SPtr<GridBuilder> builder, SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager)
 {
     this->builder           = builder;
@@ -88,6 +90,23 @@ void GridGenerator::allocArrays_BoundaryValues()
 {
     std::cout << "------read BoundaryValues------" << std::endl;
     int blocks = 0;
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    const auto numberOfPressureValues = int(builder->getPressureSize(0));
+    std::cout << "size pressure: " << numberOfPressureValues << std::endl;
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    blocks                                      = (numberOfPressureValues / para->getParH()->numberofthreads) + 1;
+    para->getParH()->pressureBC.numberOfBCnodes = blocks * para->getParH()->numberofthreads;
+    para->getParD()->pressureBC.numberOfBCnodes = para->getParH()->pressureBC.numberOfBCnodes;
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    if (numberOfPressureValues > 1)
+        {
+            cudaMemoryManager->cudaAllocPress();
+            builder->getPressureValues(para->getParH()->pressureBC.RhoBC, para->getParH()->pressureBC.k, para->getParH()->pressureBC.kN, 0);
+            cudaMemoryManager->cudaCopyPress();
+        }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -95,19 +114,17 @@ void GridGenerator::allocArrays_BoundaryValues()
     std::cout << "size slip: " << numberOfSlipValues << std::endl;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     blocks                         = (numberOfSlipValues / para->getParH()->numberofthreads) + 1;
-    para->getParH()->slipBC.kArray = blocks * para->getParH()->numberofthreads;
-    para->getParD()->slipBC.kArray = para->getParH()->slipBC.kArray;
+    para->getParH()->slipBC.numberOfBCnodes = blocks * para->getParH()->numberofthreads;
+    para->getParD()->slipBC.numberOfBCnodes = para->getParH()->slipBC.numberOfBCnodes;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    para->getParH()->numberOfSlipBCnodes = numberOfSlipValues;
-    para->getParD()->numberOfSlipBCnodes = numberOfSlipValues;
 
     if (numberOfSlipValues > 1) {
         cudaMemoryManager->cudaAllocSlipBC();
 
         builder->getSlipValues(
-            para->getParH()->slipBC.NormalX,
-            para->getParH()->slipBC.NormalY,
-            para->getParH()->slipBC.NormalY,
+            para->getParH()->slipBC.normalX,
+            para->getParH()->slipBC.normalY,
+            para->getParH()->slipBC.normalY,
             para->getParH()->slipBC.k, 0);
 
         cudaMemoryManager->cudaCopySlipBC();
@@ -119,20 +136,17 @@ void GridGenerator::allocArrays_BoundaryValues()
     std::cout << "size velocity: " << numberOfVelocityValues << std::endl;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     blocks                           = (numberOfVelocityValues / para->getParH()->numberofthreads) + 1;
-    para->getParH()->veloBC.kArray = blocks * para->getParH()->numberofthreads;
-    para->getParD()->veloBC.kArray = para->getParH()->veloBC.kArray;
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    para->getParH()->numberOfVeloBCnodes = numberOfVelocityValues;
-    para->getParD()->numberOfVeloBCnodes = numberOfVelocityValues;
+    para->getParH()->velocityBC.numberOfBCnodes = blocks * para->getParH()->numberofthreads;
+    para->getParD()->velocityBC.numberOfBCnodes = para->getParH()->velocityBC.numberOfBCnodes;
 
     if (numberOfVelocityValues > 1) {
         cudaMemoryManager->cudaAllocVeloBC();
 
         builder->getVelocityValues(
-            para->getParH()->veloBC.Vx,
-            para->getParH()->veloBC.Vy,
-            para->getParH()->veloBC.Vz,
-            para->getParH()->veloBC.k, 0);
+            para->getParH()->velocityBC.Vx,
+            para->getParH()->velocityBC.Vy,
+            para->getParH()->velocityBC.Vz,
+            para->getParH()->velocityBC.k, 0);
 
         cudaMemoryManager->cudaCopyVeloBC();
     }
@@ -140,51 +154,40 @@ void GridGenerator::allocArrays_BoundaryValues()
 
 void GridGenerator::allocArrays_BoundaryQs()
 {
+    
     std::cout << "------read BoundaryQs-------" << std::endl;
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    const auto numberOfPressureValues = (int)builder->getPressureSize(0);
+    if (numberOfPressureValues > 0)
+    {
+        std::cout << "size Pressure: " << numberOfPressureValues << std::endl;
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        //preprocessing
+        real* QQ = para->getParH()->pressureBC.q27[0];
+        unsigned int sizeQ = para->getParH()->pressureBC.numberOfBCnodes;
+        QforBoundaryConditions Q;
+        getPointersToBoundaryConditions(Q, QQ, sizeQ);
+
+        builder->getPressureQs(Q.q27, 0);
+
+        cudaMemoryManager->cudaCopyPress();
+    }
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     const auto numberOfSlipNodes = int(builder->getSlipSize(0));
     if (numberOfSlipNodes > 0) {
-        std::cout << "size velocity: " << numberOfSlipNodes << std::endl;
+        std::cout << "size slip: " << numberOfSlipNodes << std::endl;
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         // preprocessing
         real *QQ           = para->getParH()->slipBC.q27[0];
-        unsigned int sizeQ = para->getParH()->numberOfSlipBCnodes;
+        unsigned int sizeQ = para->getParH()->slipBC.numberOfBCnodes;
         QforBoundaryConditions Q;
-        Q.q27[dirE]    = &QQ[dirE * sizeQ];
-        Q.q27[dirW]    = &QQ[dirW * sizeQ];
-        Q.q27[dirN]    = &QQ[dirN * sizeQ];
-        Q.q27[dirS]    = &QQ[dirS * sizeQ];
-        Q.q27[dirT]    = &QQ[dirT * sizeQ];
-        Q.q27[dirB]    = &QQ[dirB * sizeQ];
-        Q.q27[dirNE]   = &QQ[dirNE * sizeQ];
-        Q.q27[dirSW]   = &QQ[dirSW * sizeQ];
-        Q.q27[dirSE]   = &QQ[dirSE * sizeQ];
-        Q.q27[dirNW]   = &QQ[dirNW * sizeQ];
-        Q.q27[dirTE]   = &QQ[dirTE * sizeQ];
-        Q.q27[dirBW]   = &QQ[dirBW * sizeQ];
-        Q.q27[dirBE]   = &QQ[dirBE * sizeQ];
-        Q.q27[dirTW]   = &QQ[dirTW * sizeQ];
-        Q.q27[dirTN]   = &QQ[dirTN * sizeQ];
-        Q.q27[dirBS]   = &QQ[dirBS * sizeQ];
-        Q.q27[dirBN]   = &QQ[dirBN * sizeQ];
-        Q.q27[dirTS]   = &QQ[dirTS * sizeQ];
-        Q.q27[dirREST] = &QQ[dirREST * sizeQ];
-        Q.q27[dirTNE]  = &QQ[dirTNE * sizeQ];
-        Q.q27[dirTSW]  = &QQ[dirTSW * sizeQ];
-        Q.q27[dirTSE]  = &QQ[dirTSE * sizeQ];
-        Q.q27[dirTNW]  = &QQ[dirTNW * sizeQ];
-        Q.q27[dirBNE]  = &QQ[dirBNE * sizeQ];
-        Q.q27[dirBSW]  = &QQ[dirBSW * sizeQ];
-        Q.q27[dirBSE]  = &QQ[dirBSE * sizeQ];
-        Q.q27[dirBNW]  = &QQ[dirBNW * sizeQ];
+        getPointersToBoundaryConditions(Q, QQ, sizeQ);
 
         builder->getSlipQs(Q.q27, 0);
 
         cudaMemoryManager->cudaCopySlipBC();
     }
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     const auto numberOfVelocityNodes = int(builder->getVelocitySize(0));
@@ -192,36 +195,10 @@ void GridGenerator::allocArrays_BoundaryQs()
         std::cout << "size velocity: " << numberOfVelocityNodes << std::endl;
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         // preprocessing
-        real *QQ           = para->getParH()->veloBC.q27[0];
-        unsigned int sizeQ = para->getParH()->numberOfVeloBCnodes;
+        real *QQ           = para->getParH()->velocityBC.q27[0];
+        unsigned int sizeQ = para->getParH()->velocityBC.numberOfBCnodes;
         QforBoundaryConditions Q;
-        Q.q27[dirE]    = &QQ[dirE * sizeQ];
-        Q.q27[dirW]    = &QQ[dirW * sizeQ];
-        Q.q27[dirN]    = &QQ[dirN * sizeQ];
-        Q.q27[dirS]    = &QQ[dirS * sizeQ];
-        Q.q27[dirT]    = &QQ[dirT * sizeQ];
-        Q.q27[dirB]    = &QQ[dirB * sizeQ];
-        Q.q27[dirNE]   = &QQ[dirNE * sizeQ];
-        Q.q27[dirSW]   = &QQ[dirSW * sizeQ];
-        Q.q27[dirSE]   = &QQ[dirSE * sizeQ];
-        Q.q27[dirNW]   = &QQ[dirNW * sizeQ];
-        Q.q27[dirTE]   = &QQ[dirTE * sizeQ];
-        Q.q27[dirBW]   = &QQ[dirBW * sizeQ];
-        Q.q27[dirBE]   = &QQ[dirBE * sizeQ];
-        Q.q27[dirTW]   = &QQ[dirTW * sizeQ];
-        Q.q27[dirTN]   = &QQ[dirTN * sizeQ];
-        Q.q27[dirBS]   = &QQ[dirBS * sizeQ];
-        Q.q27[dirBN]   = &QQ[dirBN * sizeQ];
-        Q.q27[dirTS]   = &QQ[dirTS * sizeQ];
-        Q.q27[dirREST] = &QQ[dirREST * sizeQ];
-        Q.q27[dirTNE]  = &QQ[dirTNE * sizeQ];
-        Q.q27[dirTSW]  = &QQ[dirTSW * sizeQ];
-        Q.q27[dirTSE]  = &QQ[dirTSE * sizeQ];
-        Q.q27[dirTNW]  = &QQ[dirTNW * sizeQ];
-        Q.q27[dirBNE]  = &QQ[dirBNE * sizeQ];
-        Q.q27[dirBSW]  = &QQ[dirBSW * sizeQ];
-        Q.q27[dirBSE]  = &QQ[dirBSE * sizeQ];
-        Q.q27[dirBNW]  = &QQ[dirBNW * sizeQ];
+        getPointersToBoundaryConditions(Q, QQ, sizeQ);
 
         builder->getVelocityQs(Q.q27, 0);
 
@@ -229,6 +206,33 @@ void GridGenerator::allocArrays_BoundaryQs()
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+    const auto numberOfGeometryNodes = builder->getGeometrySize(0);
+    std::cout << "size geometry: " << numberOfGeometryNodes << std::endl;
+    para->getParH()->geometryBC.numberOfBCnodes = numberOfGeometryNodes;
+    para->getParD()->geometryBC.numberOfBCnodes = para->getParH()->geometryBC.numberOfBCnodes;
+    if (numberOfGeometryNodes > 0)
+    {
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        cudaMemoryManager->cudaAllocGeomBC();
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        //////////////////////////////////////////////////////////////////////////
+        //Indexarray
+        builder->getGeometryIndices(para->getParH()->geometryBC.k, 0);
+        //////////////////////////////////////////////////////////////////////////
+        //preprocessing
+        real* QQ = para->getParH()->geometryBC.q27[0];
+        unsigned int sizeQ = para->getParH()->geometryBC.numberOfBCnodes;
+        QforBoundaryConditions Q;
+        getPointersToBoundaryConditions(Q, QQ, sizeQ);
+        
+        builder->getGeometryQs(Q.q27,0);
+        
+        for (uint node_i = 0; node_i < numberOfGeometryNodes; node_i++)
+        {
+            Q.q27[REST][node_i] = 0.0f;
+        }
+        cudaMemoryManager->cudaCopyGeomBC();
+    }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     std::cout << "-----finish BoundaryQs------" << std::endl;
 }
@@ -310,3 +314,33 @@ std::string GridGenerator::checkNeighbor(real x, real y, real z, int index, int
     }
     return oss.str();
 }
+
+void GridGenerator::getPointersToBoundaryConditions(QforBoundaryConditions& boundaryConditionStruct, real* subgridDistances, const unsigned int numberOfBCnodes){
+    boundaryConditionStruct.q27[E] =    &subgridDistances[E   * numberOfBCnodes];
+    boundaryConditionStruct.q27[W] =    &subgridDistances[W   * numberOfBCnodes];
+    boundaryConditionStruct.q27[N] =    &subgridDistances[N   * numberOfBCnodes];
+    boundaryConditionStruct.q27[S] =    &subgridDistances[S   * numberOfBCnodes];
+    boundaryConditionStruct.q27[T] =    &subgridDistances[T   * numberOfBCnodes];
+    boundaryConditionStruct.q27[B] =    &subgridDistances[B   * numberOfBCnodes];
+    boundaryConditionStruct.q27[NE] =   &subgridDistances[NE  * numberOfBCnodes];
+    boundaryConditionStruct.q27[SW] =   &subgridDistances[SW  * numberOfBCnodes];
+    boundaryConditionStruct.q27[SE] =   &subgridDistances[SE  * numberOfBCnodes];
+    boundaryConditionStruct.q27[NW] =   &subgridDistances[NW  * numberOfBCnodes];
+    boundaryConditionStruct.q27[TE] =   &subgridDistances[TE  * numberOfBCnodes];
+    boundaryConditionStruct.q27[BW] =   &subgridDistances[BW  * numberOfBCnodes];
+    boundaryConditionStruct.q27[BE] =   &subgridDistances[BE  * numberOfBCnodes];
+    boundaryConditionStruct.q27[TW] =   &subgridDistances[TW  * numberOfBCnodes];
+    boundaryConditionStruct.q27[TN] =   &subgridDistances[TN  * numberOfBCnodes];
+    boundaryConditionStruct.q27[BS] =   &subgridDistances[BS  * numberOfBCnodes];
+    boundaryConditionStruct.q27[BN] =   &subgridDistances[BN  * numberOfBCnodes];
+    boundaryConditionStruct.q27[TS] =   &subgridDistances[TS  * numberOfBCnodes];
+    boundaryConditionStruct.q27[REST] = &subgridDistances[REST* numberOfBCnodes];
+    boundaryConditionStruct.q27[TNE] =  &subgridDistances[TNE * numberOfBCnodes];
+    boundaryConditionStruct.q27[TSW] =  &subgridDistances[TSW * numberOfBCnodes];
+    boundaryConditionStruct.q27[TSE] =  &subgridDistances[TSE * numberOfBCnodes];
+    boundaryConditionStruct.q27[TNW] =  &subgridDistances[TNW * numberOfBCnodes];
+    boundaryConditionStruct.q27[BNE] =  &subgridDistances[BNE * numberOfBCnodes];
+    boundaryConditionStruct.q27[BSW] =  &subgridDistances[BSW * numberOfBCnodes];
+    boundaryConditionStruct.q27[BSE] =  &subgridDistances[BSE * numberOfBCnodes];
+    boundaryConditionStruct.q27[BNW] =  &subgridDistances[BNW * numberOfBCnodes];
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
index 20ad11f5a4f958473febb242723dc16d889315ad..bb77af8632df94ca952cb18eeaefb1e2cbe72bab 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
@@ -44,50 +44,55 @@ class GridBuilder;
 //! \class GridGenerator derived class of GridProvider
 //! \brief mapping the grid of grid generator to data structure for simulation
 class GridGenerator
-	: public GridProvider
+    : public GridProvider
 {
 private:
-	//! \brief string vector with channel direction
-	std::vector<std::string> channelDirections;
-	//! \brief string vector with channel direction
-	std::vector<std::string> channelBoundaryConditions;
+    //! \brief string vector with channel direction
+    std::vector<std::string> channelDirections;
+    //! \brief string vector with channel direction
+    std::vector<std::string> channelBoundaryConditions;
 
-	//! \brief shared pointer to GridBuilder object
-	//! \property builder is a shared pointer to an object of GridBuilder
-	SPtr<GridBuilder> builder;
+    //! \brief shared pointer to GridBuilder object
+    //! \property builder is a shared pointer to an object of GridBuilder
+    SPtr<GridBuilder> builder;
 
 public:
-	//! Class constructor
-	//! \param builder shared pointer to instance of GridBuilder
-	//! \param para shared pointer to instance of classParameter
-	//! \param cudaManager shared pointer to instance of class CudaMemoryManager
-	VIRTUALFLUIDS_GPU_EXPORT GridGenerator(SPtr<GridBuilder> builder, SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager);
-	//! Class default destructor
-	VIRTUALFLUIDS_GPU_EXPORT virtual ~GridGenerator();
+    //! Class constructor
+    //! \param builder shared pointer to instance of GridBuilder
+    //! \param para shared pointer to instance of classParameter
+    //! \param cudaManager shared pointer to instance of class CudaMemoryManager
+    VIRTUALFLUIDS_GPU_EXPORT GridGenerator(SPtr<GridBuilder> builder, SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager);
+    //! Class default destructor
+    VIRTUALFLUIDS_GPU_EXPORT virtual ~GridGenerator();
 
-	//! \brief allocates and initialized the data structures for Coordinates and node types
-	void allocArrays_CoordNeighborGeo() override;
-	//! \brief allocates and initialized the values at the boundary conditions
-	void allocArrays_BoundaryValues() override;
-	//! \brief allocates and initialized the sub-grid distances at the boundary conditions
-	void allocArrays_BoundaryQs() override;
-	
+    //! \brief allocates and initialized the data structures for Coordinates and node types
+    void allocArrays_CoordNeighborGeo() override;
+    //! \brief allocates and initialized the values at the boundary conditions
+    void allocArrays_BoundaryValues() override;
+    //! \brief allocates and initialized the sub-grid distances at the boundary conditions
+    void allocArrays_BoundaryQs() override;
+    
 private:
-	//! \brief verifies if there are invalid nodes, stopper nodes or wrong neighbors
-	std::string verifyNeighborIndices() const;
-	//! \brief verifies single neighbor index
-	//! \param index type integer
-	//! \param invalidNodes reference to invalid nodes
-	//! \param stopperNodes reference to stopper nodes
-	//! \param wrongNeighbors reference to wrong neighbors
-	std::string verifyNeighborIndex(int index, int &invalidNodes, int &stopperNodes, int &wrongNeighbors) const;
-	//! \brief check the neighbors
-	//! \param x,y,z lattice node position
-	//! \param numberOfWrongNeihgbors reference to the number of wrong neighbors
-	//! \param neighborIndex index of neighbor node
-	//! \param neighborX,neighborY,neighborZ neighbor lattice node position
-	//! \param direction type string
-	std::string checkNeighbor(real x, real y, real z, int index, int& numberOfWrongNeihgbors, int neighborIndex, real neighborX, real neighborY, real neighborZ, std::string direction) const;
+    //! \brief verifies if there are invalid nodes, stopper nodes or wrong neighbors
+    std::string verifyNeighborIndices() const;
+    //! \brief verifies single neighbor index
+    //! \param index type integer
+    //! \param invalidNodes reference to invalid nodes
+    //! \param stopperNodes reference to stopper nodes
+    //! \param wrongNeighbors reference to wrong neighbors
+    std::string verifyNeighborIndex(int index, int &invalidNodes, int &stopperNodes, int &wrongNeighbors) const;
+    //! \brief check the neighbors
+    //! \param x,y,z lattice node position
+    //! \param numberOfWrongNeighbors reference to the number of wrong neighbors
+    //! \param neighborIndex index of neighbor node
+    //! \param neighborX,neighborY,neighborZ neighbor lattice node position
+    //! \param direction type string
+    std::string checkNeighbor(real x, real y, real z, int index, int& numberOfWrongNeihgbors, int neighborIndex, real neighborX, real neighborY, real neighborZ, std::string direction) const;
+    //! \brief create the pointers in the struct for the BoundaryConditions from the boundary condition array
+    //! \param boundaryConditionStruct is a struct containing information about the boundary condition
+    //! \param subgridDistances is a pointer to an array containing the subgrid distances
+    //! \param numberOfBCnodes is the number of lattice nodes in the boundary condition
+    static void getPointersToBoundaryConditions(QforBoundaryConditions& boundaryConditionStruct, real* subgridDistances, const unsigned int numberOfBCnodes);
 };
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusion27chim.cu b/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusion27chim.cu
index ea4d643b397b6fc04bf973383cf4d5de341bdb89..45a91888b62fcd1d903c85a3c592fb3234857c53 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusion27chim.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusion27chim.cu
@@ -32,12 +32,12 @@
 //=======================================================================================
 /* Device code */
 #include "LBM/LB.h"
-#include "LBM/D3Q27.h"
+#include "lbm/constants/D3Q27.h"
 
 #include <lbm/constants/NumericConstants.h>
 
 using namespace vf::lbm::constant;
-
+using namespace vf::lbm::dir;
 
 ////////////////////////////////////////////////////////////////////////////////
 //! \brief forward chimera transformation \ref forwardChimera
@@ -67,7 +67,7 @@ inline __device__ void backwardChimera(real &mfa, real &mfb, real &mfc, real vv,
 
 ////////////////////////////////////////////////////////////////////////////////
 extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device_Kernel(
-	real omegaD,
+	real omegaDiffusivity,
 	uint* typeOfGridNode,
 	uint* neighborX,
 	uint* neighborY,
@@ -109,125 +109,125 @@ extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device
 		Distributions27 dist;
 		if (isEvenTimestep)
 		{
-			dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+			dist.f[E   ] = &distributions[E   *size_Mat];
+			dist.f[W   ] = &distributions[W   *size_Mat];
+			dist.f[N   ] = &distributions[N   *size_Mat];
+			dist.f[S   ] = &distributions[S   *size_Mat];
+			dist.f[T   ] = &distributions[T   *size_Mat];
+			dist.f[B   ] = &distributions[B   *size_Mat];
+			dist.f[NE  ] = &distributions[NE  *size_Mat];
+			dist.f[SW  ] = &distributions[SW  *size_Mat];
+			dist.f[SE  ] = &distributions[SE  *size_Mat];
+			dist.f[NW  ] = &distributions[NW  *size_Mat];
+			dist.f[TE  ] = &distributions[TE  *size_Mat];
+			dist.f[BW  ] = &distributions[BW  *size_Mat];
+			dist.f[BE  ] = &distributions[BE  *size_Mat];
+			dist.f[TW  ] = &distributions[TW  *size_Mat];
+			dist.f[TN  ] = &distributions[TN  *size_Mat];
+			dist.f[BS  ] = &distributions[BS  *size_Mat];
+			dist.f[BN  ] = &distributions[BN  *size_Mat];
+			dist.f[TS  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[TNE ] = &distributions[TNE *size_Mat];
+			dist.f[TSW ] = &distributions[TSW *size_Mat];
+			dist.f[TSE ] = &distributions[TSE *size_Mat];
+			dist.f[TNW ] = &distributions[TNW *size_Mat];
+			dist.f[BNE ] = &distributions[BNE *size_Mat];
+			dist.f[BSW ] = &distributions[BSW *size_Mat];
+			dist.f[BSE ] = &distributions[BSE *size_Mat];
+			dist.f[BNW ] = &distributions[BNW *size_Mat];
 		}
 		else
 		{
-			dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
+			dist.f[W   ] = &distributions[E   *size_Mat];
+			dist.f[E   ] = &distributions[W   *size_Mat];
+			dist.f[S   ] = &distributions[N   *size_Mat];
+			dist.f[N   ] = &distributions[S   *size_Mat];
+			dist.f[B   ] = &distributions[T   *size_Mat];
+			dist.f[T   ] = &distributions[B   *size_Mat];
+			dist.f[SW  ] = &distributions[NE  *size_Mat];
+			dist.f[NE  ] = &distributions[SW  *size_Mat];
+			dist.f[NW  ] = &distributions[SE  *size_Mat];
+			dist.f[SE  ] = &distributions[NW  *size_Mat];
+			dist.f[BW  ] = &distributions[TE  *size_Mat];
+			dist.f[TE  ] = &distributions[BW  *size_Mat];
+			dist.f[TW  ] = &distributions[BE  *size_Mat];
+			dist.f[BE  ] = &distributions[TW  *size_Mat];
+			dist.f[BS  ] = &distributions[TN  *size_Mat];
+			dist.f[TN  ] = &distributions[BS  *size_Mat];
+			dist.f[TS  ] = &distributions[BN  *size_Mat];
+			dist.f[BN  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[BSW ] = &distributions[TNE *size_Mat];
+			dist.f[BNE ] = &distributions[TSW *size_Mat];
+			dist.f[BNW ] = &distributions[TSE *size_Mat];
+			dist.f[BSE ] = &distributions[TNW *size_Mat];
+			dist.f[TSW ] = &distributions[BNE *size_Mat];
+			dist.f[TNE ] = &distributions[BSW *size_Mat];
+			dist.f[TNW ] = &distributions[BSE *size_Mat];
+			dist.f[TSE ] = &distributions[BNW *size_Mat];
 		}
 		////////////////////////////////////////////////////////////////////////////////
 		Distributions27 distAD;
 		if (isEvenTimestep)
 		{
-			distAD.f[dirE   ] = &distributionsAD[dirE   *size_Mat];
-			distAD.f[dirW   ] = &distributionsAD[dirW   *size_Mat];
-			distAD.f[dirN   ] = &distributionsAD[dirN   *size_Mat];
-			distAD.f[dirS   ] = &distributionsAD[dirS   *size_Mat];
-			distAD.f[dirT   ] = &distributionsAD[dirT   *size_Mat];
-			distAD.f[dirB   ] = &distributionsAD[dirB   *size_Mat];
-			distAD.f[dirNE  ] = &distributionsAD[dirNE  *size_Mat];
-			distAD.f[dirSW  ] = &distributionsAD[dirSW  *size_Mat];
-			distAD.f[dirSE  ] = &distributionsAD[dirSE  *size_Mat];
-			distAD.f[dirNW  ] = &distributionsAD[dirNW  *size_Mat];
-			distAD.f[dirTE  ] = &distributionsAD[dirTE  *size_Mat];
-			distAD.f[dirBW  ] = &distributionsAD[dirBW  *size_Mat];
-			distAD.f[dirBE  ] = &distributionsAD[dirBE  *size_Mat];
-			distAD.f[dirTW  ] = &distributionsAD[dirTW  *size_Mat];
-			distAD.f[dirTN  ] = &distributionsAD[dirTN  *size_Mat];
-			distAD.f[dirBS  ] = &distributionsAD[dirBS  *size_Mat];
-			distAD.f[dirBN  ] = &distributionsAD[dirBN  *size_Mat];
-			distAD.f[dirTS  ] = &distributionsAD[dirTS  *size_Mat];
-			distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-			distAD.f[dirTNE ] = &distributionsAD[dirTNE *size_Mat];
-			distAD.f[dirTSW ] = &distributionsAD[dirTSW *size_Mat];
-			distAD.f[dirTSE ] = &distributionsAD[dirTSE *size_Mat];
-			distAD.f[dirTNW ] = &distributionsAD[dirTNW *size_Mat];
-			distAD.f[dirBNE ] = &distributionsAD[dirBNE *size_Mat];
-			distAD.f[dirBSW ] = &distributionsAD[dirBSW *size_Mat];
-			distAD.f[dirBSE ] = &distributionsAD[dirBSE *size_Mat];
-			distAD.f[dirBNW ] = &distributionsAD[dirBNW *size_Mat];
+			distAD.f[E   ] = &distributionsAD[E   *size_Mat];
+			distAD.f[W   ] = &distributionsAD[W   *size_Mat];
+			distAD.f[N   ] = &distributionsAD[N   *size_Mat];
+			distAD.f[S   ] = &distributionsAD[S   *size_Mat];
+			distAD.f[T   ] = &distributionsAD[T   *size_Mat];
+			distAD.f[B   ] = &distributionsAD[B   *size_Mat];
+			distAD.f[NE  ] = &distributionsAD[NE  *size_Mat];
+			distAD.f[SW  ] = &distributionsAD[SW  *size_Mat];
+			distAD.f[SE  ] = &distributionsAD[SE  *size_Mat];
+			distAD.f[NW  ] = &distributionsAD[NW  *size_Mat];
+			distAD.f[TE  ] = &distributionsAD[TE  *size_Mat];
+			distAD.f[BW  ] = &distributionsAD[BW  *size_Mat];
+			distAD.f[BE  ] = &distributionsAD[BE  *size_Mat];
+			distAD.f[TW  ] = &distributionsAD[TW  *size_Mat];
+			distAD.f[TN  ] = &distributionsAD[TN  *size_Mat];
+			distAD.f[BS  ] = &distributionsAD[BS  *size_Mat];
+			distAD.f[BN  ] = &distributionsAD[BN  *size_Mat];
+			distAD.f[TS  ] = &distributionsAD[TS  *size_Mat];
+			distAD.f[REST] = &distributionsAD[REST*size_Mat];
+			distAD.f[TNE ] = &distributionsAD[TNE *size_Mat];
+			distAD.f[TSW ] = &distributionsAD[TSW *size_Mat];
+			distAD.f[TSE ] = &distributionsAD[TSE *size_Mat];
+			distAD.f[TNW ] = &distributionsAD[TNW *size_Mat];
+			distAD.f[BNE ] = &distributionsAD[BNE *size_Mat];
+			distAD.f[BSW ] = &distributionsAD[BSW *size_Mat];
+			distAD.f[BSE ] = &distributionsAD[BSE *size_Mat];
+			distAD.f[BNW ] = &distributionsAD[BNW *size_Mat];
 		}
 		else
 		{
-			distAD.f[dirW   ] = &distributionsAD[dirE   *size_Mat];
-			distAD.f[dirE   ] = &distributionsAD[dirW   *size_Mat];
-			distAD.f[dirS   ] = &distributionsAD[dirN   *size_Mat];
-			distAD.f[dirN   ] = &distributionsAD[dirS   *size_Mat];
-			distAD.f[dirB   ] = &distributionsAD[dirT   *size_Mat];
-			distAD.f[dirT   ] = &distributionsAD[dirB   *size_Mat];
-			distAD.f[dirSW  ] = &distributionsAD[dirNE  *size_Mat];
-			distAD.f[dirNE  ] = &distributionsAD[dirSW  *size_Mat];
-			distAD.f[dirNW  ] = &distributionsAD[dirSE  *size_Mat];
-			distAD.f[dirSE  ] = &distributionsAD[dirNW  *size_Mat];
-			distAD.f[dirBW  ] = &distributionsAD[dirTE  *size_Mat];
-			distAD.f[dirTE  ] = &distributionsAD[dirBW  *size_Mat];
-			distAD.f[dirTW  ] = &distributionsAD[dirBE  *size_Mat];
-			distAD.f[dirBE  ] = &distributionsAD[dirTW  *size_Mat];
-			distAD.f[dirBS  ] = &distributionsAD[dirTN  *size_Mat];
-			distAD.f[dirTN  ] = &distributionsAD[dirBS  *size_Mat];
-			distAD.f[dirTS  ] = &distributionsAD[dirBN  *size_Mat];
-			distAD.f[dirBN  ] = &distributionsAD[dirTS  *size_Mat];
-			distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-			distAD.f[dirBSW ] = &distributionsAD[dirTNE *size_Mat];
-			distAD.f[dirBNE ] = &distributionsAD[dirTSW *size_Mat];
-			distAD.f[dirBNW ] = &distributionsAD[dirTSE *size_Mat];
-			distAD.f[dirBSE ] = &distributionsAD[dirTNW *size_Mat];
-			distAD.f[dirTSW ] = &distributionsAD[dirBNE *size_Mat];
-			distAD.f[dirTNE ] = &distributionsAD[dirBSW *size_Mat];
-			distAD.f[dirTNW ] = &distributionsAD[dirBSE *size_Mat];
-			distAD.f[dirTSE ] = &distributionsAD[dirBNW *size_Mat];
+			distAD.f[W   ] = &distributionsAD[E   *size_Mat];
+			distAD.f[E   ] = &distributionsAD[W   *size_Mat];
+			distAD.f[S   ] = &distributionsAD[N   *size_Mat];
+			distAD.f[N   ] = &distributionsAD[S   *size_Mat];
+			distAD.f[B   ] = &distributionsAD[T   *size_Mat];
+			distAD.f[T   ] = &distributionsAD[B   *size_Mat];
+			distAD.f[SW  ] = &distributionsAD[NE  *size_Mat];
+			distAD.f[NE  ] = &distributionsAD[SW  *size_Mat];
+			distAD.f[NW  ] = &distributionsAD[SE  *size_Mat];
+			distAD.f[SE  ] = &distributionsAD[NW  *size_Mat];
+			distAD.f[BW  ] = &distributionsAD[TE  *size_Mat];
+			distAD.f[TE  ] = &distributionsAD[BW  *size_Mat];
+			distAD.f[TW  ] = &distributionsAD[BE  *size_Mat];
+			distAD.f[BE  ] = &distributionsAD[TW  *size_Mat];
+			distAD.f[BS  ] = &distributionsAD[TN  *size_Mat];
+			distAD.f[TN  ] = &distributionsAD[BS  *size_Mat];
+			distAD.f[TS  ] = &distributionsAD[BN  *size_Mat];
+			distAD.f[BN  ] = &distributionsAD[TS  *size_Mat];
+			distAD.f[REST] = &distributionsAD[REST*size_Mat];
+			distAD.f[BSW ] = &distributionsAD[TNE *size_Mat];
+			distAD.f[BNE ] = &distributionsAD[TSW *size_Mat];
+			distAD.f[BNW ] = &distributionsAD[TSE *size_Mat];
+			distAD.f[BSE ] = &distributionsAD[TNW *size_Mat];
+			distAD.f[TSW ] = &distributionsAD[BNE *size_Mat];
+			distAD.f[TNE ] = &distributionsAD[BSW *size_Mat];
+			distAD.f[TNW ] = &distributionsAD[BSE *size_Mat];
+			distAD.f[TSE ] = &distributionsAD[BNW *size_Mat];
 		}
 		////////////////////////////////////////////////////////////////////////////////
 		//! - Set neighbor indices (necessary for indirect addressing)
@@ -241,63 +241,63 @@ extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Set local distributions Fluid
 		//!
-		real fcbb = (dist.f[dirE   ])[k];
-		real fabb = (dist.f[dirW   ])[kw];
-		real fbcb = (dist.f[dirN   ])[k];
-		real fbab = (dist.f[dirS   ])[ks];
-		real fbbc = (dist.f[dirT   ])[k];
-		real fbba = (dist.f[dirB   ])[kb];
-		real fccb = (dist.f[dirNE  ])[k];
-		real faab = (dist.f[dirSW  ])[ksw];
-		real fcab = (dist.f[dirSE  ])[ks];
-		real facb = (dist.f[dirNW  ])[kw];
-		real fcbc = (dist.f[dirTE  ])[k];
-		real faba = (dist.f[dirBW  ])[kbw];
-		real fcba = (dist.f[dirBE  ])[kb];
-		real fabc = (dist.f[dirTW  ])[kw];
-		real fbcc = (dist.f[dirTN  ])[k];
-		real fbaa = (dist.f[dirBS  ])[kbs];
-		real fbca = (dist.f[dirBN  ])[kb];
-		real fbac = (dist.f[dirTS  ])[ks];
-		real fbbb = (dist.f[dirREST])[k];
-		real fccc = (dist.f[dirTNE ])[k];
-		real faac = (dist.f[dirTSW ])[ksw];
-		real fcac = (dist.f[dirTSE ])[ks];
-		real facc = (dist.f[dirTNW ])[kw];
-		real fcca = (dist.f[dirBNE ])[kb];
-		real faaa = (dist.f[dirBSW ])[kbsw];
-		real fcaa = (dist.f[dirBSE ])[kbs];
-		real faca = (dist.f[dirBNW ])[kbw];
+		real fcbb = (dist.f[E   ])[k];
+		real fabb = (dist.f[W   ])[kw];
+		real fbcb = (dist.f[N   ])[k];
+		real fbab = (dist.f[S   ])[ks];
+		real fbbc = (dist.f[T   ])[k];
+		real fbba = (dist.f[B   ])[kb];
+		real fccb = (dist.f[NE  ])[k];
+		real faab = (dist.f[SW  ])[ksw];
+		real fcab = (dist.f[SE  ])[ks];
+		real facb = (dist.f[NW  ])[kw];
+		real fcbc = (dist.f[TE  ])[k];
+		real faba = (dist.f[BW  ])[kbw];
+		real fcba = (dist.f[BE  ])[kb];
+		real fabc = (dist.f[TW  ])[kw];
+		real fbcc = (dist.f[TN  ])[k];
+		real fbaa = (dist.f[BS  ])[kbs];
+		real fbca = (dist.f[BN  ])[kb];
+		real fbac = (dist.f[TS  ])[ks];
+		real fbbb = (dist.f[REST])[k];
+		real fccc = (dist.f[TNE ])[k];
+		real faac = (dist.f[TSW ])[ksw];
+		real fcac = (dist.f[TSE ])[ks];
+		real facc = (dist.f[TNW ])[kw];
+		real fcca = (dist.f[BNE ])[kb];
+		real faaa = (dist.f[BSW ])[kbsw];
+		real fcaa = (dist.f[BSE ])[kbs];
+		real faca = (dist.f[BNW ])[kbw];
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Set local distributions Advection Diffusion
 		//!
-		real mfcbb = (distAD.f[dirE   ])[k];
-		real mfabb = (distAD.f[dirW   ])[kw];
-		real mfbcb = (distAD.f[dirN   ])[k];
-		real mfbab = (distAD.f[dirS   ])[ks];
-		real mfbbc = (distAD.f[dirT   ])[k];
-		real mfbba = (distAD.f[dirB   ])[kb];
-		real mfccb = (distAD.f[dirNE  ])[k];
-		real mfaab = (distAD.f[dirSW  ])[ksw];
-		real mfcab = (distAD.f[dirSE  ])[ks];
-		real mfacb = (distAD.f[dirNW  ])[kw];
-		real mfcbc = (distAD.f[dirTE  ])[k];
-		real mfaba = (distAD.f[dirBW  ])[kbw];
-		real mfcba = (distAD.f[dirBE  ])[kb];
-		real mfabc = (distAD.f[dirTW  ])[kw];
-		real mfbcc = (distAD.f[dirTN  ])[k];
-		real mfbaa = (distAD.f[dirBS  ])[kbs];
-		real mfbca = (distAD.f[dirBN  ])[kb];
-		real mfbac = (distAD.f[dirTS  ])[ks];
-		real mfbbb = (distAD.f[dirREST])[k];
-		real mfccc = (distAD.f[dirTNE ])[k];
-		real mfaac = (distAD.f[dirTSW ])[ksw];
-		real mfcac = (distAD.f[dirTSE ])[ks];
-		real mfacc = (distAD.f[dirTNW ])[kw];
-		real mfcca = (distAD.f[dirBNE ])[kb];
-		real mfaaa = (distAD.f[dirBSW ])[kbsw];
-		real mfcaa = (distAD.f[dirBSE ])[kbs];
-		real mfaca = (distAD.f[dirBNW ])[kbw];
+		real mfcbb = (distAD.f[E   ])[k];
+		real mfabb = (distAD.f[W   ])[kw];
+		real mfbcb = (distAD.f[N   ])[k];
+		real mfbab = (distAD.f[S   ])[ks];
+		real mfbbc = (distAD.f[T   ])[k];
+		real mfbba = (distAD.f[B   ])[kb];
+		real mfccb = (distAD.f[NE  ])[k];
+		real mfaab = (distAD.f[SW  ])[ksw];
+		real mfcab = (distAD.f[SE  ])[ks];
+		real mfacb = (distAD.f[NW  ])[kw];
+		real mfcbc = (distAD.f[TE  ])[k];
+		real mfaba = (distAD.f[BW  ])[kbw];
+		real mfcba = (distAD.f[BE  ])[kb];
+		real mfabc = (distAD.f[TW  ])[kw];
+		real mfbcc = (distAD.f[TN  ])[k];
+		real mfbaa = (distAD.f[BS  ])[kbs];
+		real mfbca = (distAD.f[BN  ])[kb];
+		real mfbac = (distAD.f[TS  ])[ks];
+		real mfbbb = (distAD.f[REST])[k];
+		real mfccc = (distAD.f[TNE ])[k];
+		real mfaac = (distAD.f[TSW ])[ksw];
+		real mfcac = (distAD.f[TSE ])[ks];
+		real mfacc = (distAD.f[TNW ])[kw];
+		real mfcca = (distAD.f[BNE ])[kb];
+		real mfaaa = (distAD.f[BSW ])[kbsw];
+		real mfcaa = (distAD.f[BSE ])[kbs];
+		real mfaca = (distAD.f[BNW ])[kbw];
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Calculate density and velocity using pyramid summation for low round-off errors as in Eq. (J1)-(J3) \ref
 		//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
@@ -347,7 +347,7 @@ extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device
 		real vy2 = vvy*vvy;
 		real vz2 = vvz*vvz;
 		////////////////////////////////////////////////////////////////////////////////////
-		//real omegaD = c2o1 / (c6o1 * diffusivity + c1o1);
+		//real omegaDiffusivity = c2o1 / (c6o1 * diffusivity + c1o1);
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Chimera transform from distributions to central moments as defined in Eq. (43)-(45) in \ref
 		//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
@@ -406,9 +406,9 @@ extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device
 		real Mccb = mfccb - mfaab*c1o9;
 
 		// collision of 1st order moments
-		mfbaa *= c1o1 - omegaD;
-		mfaba *= c1o1 - omegaD;
-		mfaab *= c1o1 - omegaD;
+		mfbaa *= c1o1 - omegaDiffusivity;
+		mfaba *= c1o1 - omegaDiffusivity;
+		mfaab *= c1o1 - omegaDiffusivity;
 
 		// equilibration of 3rd order moments
 		Mabc = c0o1;
@@ -503,33 +503,33 @@ extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device
 		//! stored arrays dependent on timestep is based on the esoteric twist algorithm
 		//! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
 		//!
-		(distAD.f[dirE   ])[k   ] = mfabb;
-		(distAD.f[dirW   ])[kw  ] = mfcbb;
-		(distAD.f[dirN   ])[k   ] = mfbab;
-		(distAD.f[dirS   ])[ks  ] = mfbcb;
-		(distAD.f[dirT   ])[k   ] = mfbba;
-		(distAD.f[dirB   ])[kb  ] = mfbbc;
-		(distAD.f[dirNE  ])[k   ] = mfaab;
-		(distAD.f[dirSW  ])[ksw ] = mfccb;
-		(distAD.f[dirSE  ])[ks  ] = mfacb;
-		(distAD.f[dirNW  ])[kw  ] = mfcab;
-		(distAD.f[dirTE  ])[k   ] = mfaba;
-		(distAD.f[dirBW  ])[kbw ] = mfcbc;
-		(distAD.f[dirBE  ])[kb  ] = mfabc;
-		(distAD.f[dirTW  ])[kw  ] = mfcba;
-		(distAD.f[dirTN  ])[k   ] = mfbaa;
-		(distAD.f[dirBS  ])[kbs ] = mfbcc;
-		(distAD.f[dirBN  ])[kb  ] = mfbac;
-		(distAD.f[dirTS  ])[ks  ] = mfbca;
-		(distAD.f[dirREST])[k   ] = mfbbb;
-		(distAD.f[dirTNE ])[k   ] = mfaaa;
-		(distAD.f[dirTSE ])[ks  ] = mfaca;
-		(distAD.f[dirBNE ])[kb  ] = mfaac;
-		(distAD.f[dirBSE ])[kbs ] = mfacc;
-		(distAD.f[dirTNW ])[kw  ] = mfcaa;
-		(distAD.f[dirTSW ])[ksw ] = mfcca;
-		(distAD.f[dirBNW ])[kbw ] = mfcac;
-		(distAD.f[dirBSW ])[kbsw] = mfccc;
+		(distAD.f[E   ])[k   ] = mfabb;
+		(distAD.f[W   ])[kw  ] = mfcbb;
+		(distAD.f[N   ])[k   ] = mfbab;
+		(distAD.f[S   ])[ks  ] = mfbcb;
+		(distAD.f[T   ])[k   ] = mfbba;
+		(distAD.f[B   ])[kb  ] = mfbbc;
+		(distAD.f[NE  ])[k   ] = mfaab;
+		(distAD.f[SW  ])[ksw ] = mfccb;
+		(distAD.f[SE  ])[ks  ] = mfacb;
+		(distAD.f[NW  ])[kw  ] = mfcab;
+		(distAD.f[TE  ])[k   ] = mfaba;
+		(distAD.f[BW  ])[kbw ] = mfcbc;
+		(distAD.f[BE  ])[kb  ] = mfabc;
+		(distAD.f[TW  ])[kw  ] = mfcba;
+		(distAD.f[TN  ])[k   ] = mfbaa;
+		(distAD.f[BS  ])[kbs ] = mfbcc;
+		(distAD.f[BN  ])[kb  ] = mfbac;
+		(distAD.f[TS  ])[ks  ] = mfbca;
+		(distAD.f[REST])[k   ] = mfbbb;
+		(distAD.f[TNE ])[k   ] = mfaaa;
+		(distAD.f[TSE ])[ks  ] = mfaca;
+		(distAD.f[BNE ])[kb  ] = mfaac;
+		(distAD.f[BSE ])[kbs ] = mfacc;
+		(distAD.f[TNW ])[kw  ] = mfcaa;
+		(distAD.f[TSW ])[ksw ] = mfcca;
+		(distAD.f[BNW ])[kbw ] = mfcac;
+		(distAD.f[BSW ])[kbsw] = mfccc;
 	}
 }
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusionBCs27.cu b/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusionBCs27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..d961347005f4984065a7189fb9747be5d493a674
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/AdvectionDiffusionBCs27.cu
@@ -0,0 +1,472 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file AdvectionDiffusion27chim.cu
+//! \ingroup GPU
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h"
+#include "lbm/constants/D3Q27.h"
+#include <lbm/constants/NumericConstants.h>
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+////////////////////////////////////////////////////////////////////////////////
+inline __device__ real calcDistributionBC_AD_interpol(real q, real weight, real v, real v_sq, real f, real finf, real omegaDiffusivity, real jTangential, real concentration) {
+    real feq = weight * concentration * (c1o1 + c3o1 * v + c9o2 * v * v * concentration - v_sq * concentration);
+    return (c1o1 - q) / (c1o1 + q) * ((f - feq * omegaDiffusivity) / (c1o1 - omegaDiffusivity)) + (q * (f + finf) - c6o1 * weight * (jTangential)) / (c1o1 + q);
+}
+////////////////////////////////////////////////////////////////////////////////
+inline __device__ real calcDistributionBC_AD(real q, real weight, real v, real v_sq, real f, real finf, real omegaDiffusivity, real jTangential, real concentration) {
+    return f - c6o1 * weight * jTangential;
+}
+
+
+// has to be excecuted before Fluid BCs
+//////////////////////////////////////////////////////////////////////////////
+extern "C" __global__ void AD_SlipVelDeviceComp(
+    real *normalX,
+    real *normalY,
+    real *normalZ,
+    real *distributions,
+    real *distributionsAD,
+    int *QindexArray,
+    real *Qarrays,
+    uint numberOfBCnodes,
+    real omegaDiffusivity,
+    uint* neighborX,
+    uint* neighborY,
+    uint* neighborZ,
+    uint size_Mat,
+    bool isEvenTimestep)
+{
+    Distributions27 D;
+    if (isEvenTimestep)
+    {
+        D.f[E   ] = &distributions[E    * size_Mat];
+        D.f[W   ] = &distributions[W    * size_Mat];
+        D.f[N   ] = &distributions[N    * size_Mat];
+        D.f[S   ] = &distributions[S    * size_Mat];
+        D.f[T   ] = &distributions[T    * size_Mat];
+        D.f[B   ] = &distributions[B    * size_Mat];
+        D.f[NE  ] = &distributions[NE   * size_Mat];
+        D.f[SW  ] = &distributions[SW   * size_Mat];
+        D.f[SE  ] = &distributions[SE   * size_Mat];
+        D.f[NW  ] = &distributions[NW   * size_Mat];
+        D.f[TE  ] = &distributions[TE   * size_Mat];
+        D.f[BW  ] = &distributions[BW   * size_Mat];
+        D.f[BE  ] = &distributions[BE   * size_Mat];
+        D.f[TW  ] = &distributions[TW   * size_Mat];
+        D.f[TN  ] = &distributions[TN   * size_Mat];
+        D.f[BS  ] = &distributions[BS   * size_Mat];
+        D.f[BN  ] = &distributions[BN   * size_Mat];
+        D.f[TS  ] = &distributions[TS   * size_Mat];
+        D.f[REST] = &distributions[REST * size_Mat];
+        D.f[TNE ] = &distributions[TNE  * size_Mat];
+        D.f[TSW ] = &distributions[TSW  * size_Mat];
+        D.f[TSE ] = &distributions[TSE  * size_Mat];
+        D.f[TNW ] = &distributions[TNW  * size_Mat];
+        D.f[BNE ] = &distributions[BNE  * size_Mat];
+        D.f[BSW ] = &distributions[BSW  * size_Mat];
+        D.f[BSE ] = &distributions[BSE  * size_Mat];
+        D.f[BNW ] = &distributions[BNW  * size_Mat];
+    }
+    else
+    {
+        D.f[W   ] = &distributions[E    * size_Mat];
+        D.f[E   ] = &distributions[W    * size_Mat];
+        D.f[S   ] = &distributions[N    * size_Mat];
+        D.f[N   ] = &distributions[S    * size_Mat];
+        D.f[B   ] = &distributions[T    * size_Mat];
+        D.f[T   ] = &distributions[B    * size_Mat];
+        D.f[SW  ] = &distributions[NE   * size_Mat];
+        D.f[NE  ] = &distributions[SW   * size_Mat];
+        D.f[NW  ] = &distributions[SE   * size_Mat];
+        D.f[SE  ] = &distributions[NW   * size_Mat];
+        D.f[BW  ] = &distributions[TE   * size_Mat];
+        D.f[TE  ] = &distributions[BW   * size_Mat];
+        D.f[TW  ] = &distributions[BE   * size_Mat];
+        D.f[BE  ] = &distributions[TW   * size_Mat];
+        D.f[BS  ] = &distributions[TN   * size_Mat];
+        D.f[TN  ] = &distributions[BS   * size_Mat];
+        D.f[TS  ] = &distributions[BN   * size_Mat];
+        D.f[BN  ] = &distributions[TS   * size_Mat];
+        D.f[REST] = &distributions[REST * size_Mat];
+        D.f[TNE ] = &distributions[BSW  * size_Mat];
+        D.f[TSW ] = &distributions[BNE  * size_Mat];
+        D.f[TSE ] = &distributions[BNW  * size_Mat];
+        D.f[TNW ] = &distributions[BSE  * size_Mat];
+        D.f[BNE ] = &distributions[TSW  * size_Mat];
+        D.f[BSW ] = &distributions[TNE  * size_Mat];
+        D.f[BSE ] = &distributions[TNW  * size_Mat];
+        D.f[BNW ] = &distributions[TSE  * size_Mat];
+    }
+    ////////////////////////////////////////////////////////////////////////////////
+    Distributions27 DAD;
+    if (isEvenTimestep)
+    {
+        DAD.f[E   ] = &distributionsAD[E    * size_Mat];
+        DAD.f[W   ] = &distributionsAD[W    * size_Mat];
+        DAD.f[N   ] = &distributionsAD[N    * size_Mat];
+        DAD.f[S   ] = &distributionsAD[S    * size_Mat];
+        DAD.f[T   ] = &distributionsAD[T    * size_Mat];
+        DAD.f[B   ] = &distributionsAD[B    * size_Mat];
+        DAD.f[NE  ] = &distributionsAD[NE   * size_Mat];
+        DAD.f[SW  ] = &distributionsAD[SW   * size_Mat];
+        DAD.f[SE  ] = &distributionsAD[SE   * size_Mat];
+        DAD.f[NW  ] = &distributionsAD[NW   * size_Mat];
+        DAD.f[TE  ] = &distributionsAD[TE   * size_Mat];
+        DAD.f[BW  ] = &distributionsAD[BW   * size_Mat];
+        DAD.f[BE  ] = &distributionsAD[BE   * size_Mat];
+        DAD.f[TW  ] = &distributionsAD[TW   * size_Mat];
+        DAD.f[TN  ] = &distributionsAD[TN   * size_Mat];
+        DAD.f[BS  ] = &distributionsAD[BS   * size_Mat];
+        DAD.f[BN  ] = &distributionsAD[BN   * size_Mat];
+        DAD.f[TS  ] = &distributionsAD[TS   * size_Mat];
+        DAD.f[REST] = &distributionsAD[REST * size_Mat];
+        DAD.f[TNE ] = &distributionsAD[TNE  * size_Mat];
+        DAD.f[TSW ] = &distributionsAD[TSW  * size_Mat];
+        DAD.f[TSE ] = &distributionsAD[TSE  * size_Mat];
+        DAD.f[TNW ] = &distributionsAD[TNW  * size_Mat];
+        DAD.f[BNE ] = &distributionsAD[BNE  * size_Mat];
+        DAD.f[BSW ] = &distributionsAD[BSW  * size_Mat];
+        DAD.f[BSE ] = &distributionsAD[BSE  * size_Mat];
+        DAD.f[BNW ] = &distributionsAD[BNW  * size_Mat];
+    }
+    else
+    {
+        DAD.f[W   ] = &distributionsAD[E    * size_Mat];
+        DAD.f[E   ] = &distributionsAD[W    * size_Mat];
+        DAD.f[S   ] = &distributionsAD[N    * size_Mat];
+        DAD.f[N   ] = &distributionsAD[S    * size_Mat];
+        DAD.f[B   ] = &distributionsAD[T    * size_Mat];
+        DAD.f[T   ] = &distributionsAD[B    * size_Mat];
+        DAD.f[SW  ] = &distributionsAD[NE   * size_Mat];
+        DAD.f[NE  ] = &distributionsAD[SW   * size_Mat];
+        DAD.f[NW  ] = &distributionsAD[SE   * size_Mat];
+        DAD.f[SE  ] = &distributionsAD[NW   * size_Mat];
+        DAD.f[BW  ] = &distributionsAD[TE   * size_Mat];
+        DAD.f[TE  ] = &distributionsAD[BW   * size_Mat];
+        DAD.f[TW  ] = &distributionsAD[BE   * size_Mat];
+        DAD.f[BE  ] = &distributionsAD[TW   * size_Mat];
+        DAD.f[BS  ] = &distributionsAD[TN   * size_Mat];
+        DAD.f[TN  ] = &distributionsAD[BS   * size_Mat];
+        DAD.f[TS  ] = &distributionsAD[BN   * size_Mat];
+        DAD.f[BN  ] = &distributionsAD[TS   * size_Mat];
+        DAD.f[REST] = &distributionsAD[REST * size_Mat];
+        DAD.f[TNE ] = &distributionsAD[BSW  * size_Mat];
+        DAD.f[TSW ] = &distributionsAD[BNE  * size_Mat];
+        DAD.f[TSE ] = &distributionsAD[BNW  * size_Mat];
+        DAD.f[TNW ] = &distributionsAD[BSE  * size_Mat];
+        DAD.f[BNE ] = &distributionsAD[TSW  * size_Mat];
+        DAD.f[BSW ] = &distributionsAD[TNE  * size_Mat];
+        DAD.f[BSE ] = &distributionsAD[TNW  * size_Mat];
+        DAD.f[BNW ] = &distributionsAD[TSE  * size_Mat];
+    }
+    ////////////////////////////////////////////////////////////////////////////////
+    const unsigned  x = threadIdx.x;  // Globaler x-Index
+    const unsigned  y = blockIdx.x;   // Globaler y-Index
+    const unsigned  z = blockIdx.y;   // Globaler z-Index
+
+    const unsigned nx = blockDim.x;
+    const unsigned ny = gridDim.x;
+
+    const unsigned k = nx * (ny * z + y) + x;
+    //////////////////////////////////////////////////////////////////////////
+
+    if (k < numberOfBCnodes)
+    {
+        ////////////////////////////////////////////////////////////////////////////////
+        real NormX = normalX[k];
+        real NormY = normalY[k];
+        real NormZ = normalZ[k];
+        ////////////////////////////////////////////////////////////////////////////////
+        real* q_dirE, * q_dirW, * q_dirN, * q_dirS, * q_dirT, * q_dirB,
+            * q_dirNE, * q_dirSW, * q_dirSE, * q_dirNW, * q_dirTE, * q_dirBW,
+            * q_dirBE, * q_dirTW, * q_dirTN, * q_dirBS, * q_dirBN, * q_dirTS,
+            * q_dirTNE, * q_dirTSW, * q_dirTSE, * q_dirTNW, * q_dirBNE, * q_dirBSW,
+            * q_dirBSE, * q_dirBNW;
+        q_dirE   = &Qarrays[E   * numberOfBCnodes];
+        q_dirW   = &Qarrays[W   * numberOfBCnodes];
+        q_dirN   = &Qarrays[N   * numberOfBCnodes];
+        q_dirS   = &Qarrays[S   * numberOfBCnodes];
+        q_dirT   = &Qarrays[T   * numberOfBCnodes];
+        q_dirB   = &Qarrays[B   * numberOfBCnodes];
+        q_dirNE  = &Qarrays[NE  * numberOfBCnodes];
+        q_dirSW  = &Qarrays[SW  * numberOfBCnodes];
+        q_dirSE  = &Qarrays[SE  * numberOfBCnodes];
+        q_dirNW  = &Qarrays[NW  * numberOfBCnodes];
+        q_dirTE  = &Qarrays[TE  * numberOfBCnodes];
+        q_dirBW  = &Qarrays[BW  * numberOfBCnodes];
+        q_dirBE  = &Qarrays[BE  * numberOfBCnodes];
+        q_dirTW  = &Qarrays[TW  * numberOfBCnodes];
+        q_dirTN  = &Qarrays[TN  * numberOfBCnodes];
+        q_dirBS  = &Qarrays[BS  * numberOfBCnodes];
+        q_dirBN  = &Qarrays[BN  * numberOfBCnodes];
+        q_dirTS  = &Qarrays[TS  * numberOfBCnodes];
+        q_dirTNE = &Qarrays[TNE * numberOfBCnodes];
+        q_dirTSW = &Qarrays[TSW * numberOfBCnodes];
+        q_dirTSE = &Qarrays[TSE * numberOfBCnodes];
+        q_dirTNW = &Qarrays[TNW * numberOfBCnodes];
+        q_dirBNE = &Qarrays[BNE * numberOfBCnodes];
+        q_dirBSW = &Qarrays[BSW * numberOfBCnodes];
+        q_dirBSE = &Qarrays[BSE * numberOfBCnodes];
+        q_dirBNW = &Qarrays[BNW * numberOfBCnodes];
+        ////////////////////////////////////////////////////////////////////////////////
+        //index
+        unsigned int KQK   = QindexArray[k];
+        unsigned int kzero = KQK;
+        unsigned int ke    = KQK;
+        unsigned int kw    = neighborX[KQK];
+        unsigned int kn    = KQK;
+        unsigned int ks    = neighborY[KQK];
+        unsigned int kt    = KQK;
+        unsigned int kb    = neighborZ[KQK];
+        unsigned int ksw   = neighborY[kw];
+        unsigned int kne   = KQK;
+        unsigned int kse   = ks;
+        unsigned int knw   = kw;
+        unsigned int kbw   = neighborZ[kw];
+        unsigned int kte   = KQK;
+        unsigned int kbe   = kb;
+        unsigned int ktw   = kw;
+        unsigned int kbs   = neighborZ[ks];
+        unsigned int ktn   = KQK;
+        unsigned int kbn   = kb;
+        unsigned int kts   = ks;
+        unsigned int ktse  = ks;
+        unsigned int kbnw  = kbw;
+        unsigned int ktnw  = kw;
+        unsigned int kbse  = kbs;
+        unsigned int ktsw  = ksw;
+        unsigned int kbne  = kb;
+        unsigned int ktne  = KQK;
+        unsigned int kbsw  = neighborZ[ksw];
+        ////////////////////////////////////////////////////////////////////////////////
+        real f_E, f_W, f_N, f_S, f_T, f_B, f_NE, f_SW, f_SE, f_NW, f_TE, f_BW, f_BE,
+            f_TW, f_TN, f_BS, f_BN, f_TS, f_TNE, f_TSW, f_TSE, f_TNW, f_BNE, f_BSW, f_BSE, f_BNW;
+
+        f_W   = (D.f[E])[ke];
+        f_E   = (D.f[W])[kw];
+        f_S   = (D.f[N])[kn];
+        f_N   = (D.f[S])[ks];
+        f_B   = (D.f[T])[kt];
+        f_T   = (D.f[B])[kb];
+        f_SW  = (D.f[NE])[kne];
+        f_NE  = (D.f[SW])[ksw];
+        f_NW  = (D.f[SE])[kse];
+        f_SE  = (D.f[NW])[knw];
+        f_BW  = (D.f[TE])[kte];
+        f_TE  = (D.f[BW])[kbw];
+        f_TW  = (D.f[BE])[kbe];
+        f_BE  = (D.f[TW])[ktw];
+        f_BS  = (D.f[TN])[ktn];
+        f_TN  = (D.f[BS])[kbs];
+        f_TS  = (D.f[BN])[kbn];
+        f_BN  = (D.f[TS])[kts];
+        f_BSW = (D.f[TNE])[ktne];
+        f_BNE = (D.f[TSW])[ktsw];
+        f_BNW = (D.f[TSE])[ktse];
+        f_BSE = (D.f[TNW])[ktnw];
+        f_TSW = (D.f[BNE])[kbne];
+        f_TNE = (D.f[BSW])[kbsw];
+        f_TNW = (D.f[BSE])[kbse];
+        f_TSE = (D.f[BNW])[kbnw];
+        ////////////////////////////////////////////////////////////////////////////////
+        real vx1, vx2, vx3, drho, q;
+        drho = f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
+            f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW +
+            f_T + f_B + f_N + f_S + f_E + f_W + ((D.f[REST])[kzero]);
+
+        vx1 = (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+            ((f_BE - f_TW) + (f_TE - f_BW)) + ((f_SE - f_NW) + (f_NE - f_SW)) +
+            (f_E - f_W)) / (c1o1 + drho);
+
+
+        vx2 = ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+            ((f_BN - f_TS) + (f_TN - f_BS)) + (-(f_SE - f_NW) + (f_NE - f_SW)) +
+            (f_N - f_S)) / (c1o1 + drho);
+
+        vx3 = (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
+            (-(f_BN - f_TS) + (f_TN - f_BS)) + ((f_TE - f_BW) - (f_BE - f_TW)) +
+            (f_T - f_B)) / (c1o1 + drho);
+
+        real cu_sq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3) * (c1o1 + drho);
+
+        ////////////////////////////////////////////////////////////////////////////////
+        f_W   = (DAD.f[E])[ke];
+        f_E   = (DAD.f[W])[kw];
+        f_S   = (DAD.f[N])[kn];
+        f_N   = (DAD.f[S])[ks];
+        f_B   = (DAD.f[T])[kt];
+        f_T   = (DAD.f[B])[kb];
+        f_SW  = (DAD.f[NE])[kne];
+        f_NE  = (DAD.f[SW])[ksw];
+        f_NW  = (DAD.f[SE])[kse];
+        f_SE  = (DAD.f[NW])[knw];
+        f_BW  = (DAD.f[TE])[kte];
+        f_TE  = (DAD.f[BW])[kbw];
+        f_TW  = (DAD.f[BE])[kbe];
+        f_BE  = (DAD.f[TW])[ktw];
+        f_BS  = (DAD.f[TN])[ktn];
+        f_TN  = (DAD.f[BS])[kbs];
+        f_TS  = (DAD.f[BN])[kbn];
+        f_BN  = (DAD.f[TS])[kts];
+        f_BSW = (DAD.f[TNE])[ktne];
+        f_BNE = (DAD.f[TSW])[ktsw];
+        f_BNW = (DAD.f[TSE])[ktse];
+        f_BSE = (DAD.f[TNW])[ktnw];
+        f_TSW = (DAD.f[BNE])[kbne];
+        f_TNE = (DAD.f[BSW])[kbsw];
+        f_TNW = (DAD.f[BSE])[kbse];
+        f_TSE = (DAD.f[BNW])[kbnw];
+        //////////////////////////////////////////////////////////////////////////
+        if (!isEvenTimestep)
+        {
+            DAD.f[E   ] = &distributionsAD[E    * size_Mat];
+            DAD.f[W   ] = &distributionsAD[W    * size_Mat];
+            DAD.f[N   ] = &distributionsAD[N    * size_Mat];
+            DAD.f[S   ] = &distributionsAD[S    * size_Mat];
+            DAD.f[T   ] = &distributionsAD[T    * size_Mat];
+            DAD.f[B   ] = &distributionsAD[B    * size_Mat];
+            DAD.f[NE  ] = &distributionsAD[NE   * size_Mat];
+            DAD.f[SW  ] = &distributionsAD[SW   * size_Mat];
+            DAD.f[SE  ] = &distributionsAD[SE   * size_Mat];
+            DAD.f[NW  ] = &distributionsAD[NW   * size_Mat];
+            DAD.f[TE  ] = &distributionsAD[TE   * size_Mat];
+            DAD.f[BW  ] = &distributionsAD[BW   * size_Mat];
+            DAD.f[BE  ] = &distributionsAD[BE   * size_Mat];
+            DAD.f[TW  ] = &distributionsAD[TW   * size_Mat];
+            DAD.f[TN  ] = &distributionsAD[TN   * size_Mat];
+            DAD.f[BS  ] = &distributionsAD[BS   * size_Mat];
+            DAD.f[BN  ] = &distributionsAD[BN   * size_Mat];
+            DAD.f[TS  ] = &distributionsAD[TS   * size_Mat];
+            DAD.f[REST] = &distributionsAD[REST * size_Mat];
+            DAD.f[TNE ] = &distributionsAD[TNE  * size_Mat];
+            DAD.f[TSW ] = &distributionsAD[TSW  * size_Mat];
+            DAD.f[TSE ] = &distributionsAD[TSE  * size_Mat];
+            DAD.f[TNW ] = &distributionsAD[TNW  * size_Mat];
+            DAD.f[BNE ] = &distributionsAD[BNE  * size_Mat];
+            DAD.f[BSW ] = &distributionsAD[BSW  * size_Mat];
+            DAD.f[BSE ] = &distributionsAD[BSE  * size_Mat];
+            DAD.f[BNW ] = &distributionsAD[BNW  * size_Mat];
+        }
+        else
+        {
+            DAD.f[W   ] = &distributionsAD[E    * size_Mat];
+            DAD.f[E   ] = &distributionsAD[W    * size_Mat];
+            DAD.f[S   ] = &distributionsAD[N    * size_Mat];
+            DAD.f[N   ] = &distributionsAD[S    * size_Mat];
+            DAD.f[B   ] = &distributionsAD[T    * size_Mat];
+            DAD.f[T   ] = &distributionsAD[B    * size_Mat];
+            DAD.f[SW  ] = &distributionsAD[NE   * size_Mat];
+            DAD.f[NE  ] = &distributionsAD[SW   * size_Mat];
+            DAD.f[NW  ] = &distributionsAD[SE   * size_Mat];
+            DAD.f[SE  ] = &distributionsAD[NW   * size_Mat];
+            DAD.f[BW  ] = &distributionsAD[TE   * size_Mat];
+            DAD.f[TE  ] = &distributionsAD[BW   * size_Mat];
+            DAD.f[TW  ] = &distributionsAD[BE   * size_Mat];
+            DAD.f[BE  ] = &distributionsAD[TW   * size_Mat];
+            DAD.f[BS  ] = &distributionsAD[TN   * size_Mat];
+            DAD.f[TN  ] = &distributionsAD[BS   * size_Mat];
+            DAD.f[TS  ] = &distributionsAD[BN   * size_Mat];
+            DAD.f[BN  ] = &distributionsAD[TS   * size_Mat];
+            DAD.f[REST] = &distributionsAD[REST * size_Mat];
+            DAD.f[TNE ] = &distributionsAD[BSW  * size_Mat];
+            DAD.f[TSW ] = &distributionsAD[BNE  * size_Mat];
+            DAD.f[TSE ] = &distributionsAD[BNW  * size_Mat];
+            DAD.f[TNW ] = &distributionsAD[BSE  * size_Mat];
+            DAD.f[BNE ] = &distributionsAD[TSW  * size_Mat];
+            DAD.f[BSW ] = &distributionsAD[TNE  * size_Mat];
+            DAD.f[BSE ] = &distributionsAD[TNW  * size_Mat];
+            DAD.f[BNW ] = &distributionsAD[TSE  * size_Mat];
+        }
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        real concentration =
+            f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
+            f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW +
+            f_T + f_B + f_N + f_S + f_E + f_W + ((D.f[REST])[kzero]);
+
+        real jx1 =
+            (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+            ((f_BE - f_TW) + (f_TE - f_BW)) + ((f_SE - f_NW) + (f_NE - f_SW)) +
+            (f_E - f_W)) - (vx1 * concentration);
+
+        real jx2 =
+            ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+            ((f_BN - f_TS) + (f_TN - f_BS)) + (-(f_SE - f_NW) + (f_NE - f_SW)) +
+            (f_N - f_S)) - (vx2 * concentration);
+
+        real jx3 =
+            (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
+            (-(f_BN - f_TS) + (f_TN - f_BS)) + ((f_TE - f_BW) - (f_BE - f_TW)) +
+            (f_T - f_B)) - (vx3 * concentration);
+
+        //jx1 *= (c2o1 - omegaDiffusivity) / (c2o1 - c2o1 * omegaDiffusivity);
+        //jx2 *= (c2o1 - omegaDiffusivity) / (c2o1 - c2o1 * omegaDiffusivity);
+        //jx3 *= (c2o1 - omegaDiffusivity) / (c2o1 - c2o1 * omegaDiffusivity);
+
+        real NormJ = jx1 * NormX + jx2 * NormY + jx3 * NormZ;
+
+        real jTan1 = jx1 - NormJ * NormX;
+        real jTan2 = jx2 - NormJ * NormY;
+        real jTan3 = jx3 - NormJ * NormZ;
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        q = q_dirE[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[W  ])[kw  ] = calcDistributionBC_AD(q, c2o27,   vx1,         cu_sq, f_E,   f_W,   omegaDiffusivity,        jTan1,       concentration); }
+        q = q_dirW[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[E  ])[ke  ] = calcDistributionBC_AD(q, c2o27,  -vx1,         cu_sq, f_W,   f_E,   omegaDiffusivity,       -jTan1,       concentration); }
+        q = q_dirN[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[S  ])[ks  ] = calcDistributionBC_AD(q, c2o27,   vx2,         cu_sq, f_N,   f_S,   omegaDiffusivity,        jTan2,       concentration); }
+        q = q_dirS[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[N  ])[kn  ] = calcDistributionBC_AD(q, c2o27,  -vx2,         cu_sq, f_S,   f_N,   omegaDiffusivity,       -jTan2,       concentration); }
+        q = q_dirT[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[B  ])[kb  ] = calcDistributionBC_AD(q, c2o27,   vx3,         cu_sq, f_T,   f_B,   omegaDiffusivity,        jTan3,       concentration); }
+        q = q_dirB[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[T  ])[kt  ] = calcDistributionBC_AD(q, c2o27,  -vx3,         cu_sq, f_B,   f_T,   omegaDiffusivity,       -jTan3,       concentration); }
+        q = q_dirNE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[SW ])[ksw ] = calcDistributionBC_AD(q, c1o54,   vx1+vx2,     cu_sq, f_NE,  f_SW,  omegaDiffusivity,  jTan1+jTan2,       concentration); }
+        q = q_dirSW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[NE ])[kne ] = calcDistributionBC_AD(q, c1o54,  -vx1-vx2,     cu_sq, f_SW,  f_NE,  omegaDiffusivity, -jTan1-jTan2,       concentration); }
+        q = q_dirSE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[NW ])[knw ] = calcDistributionBC_AD(q, c1o54,   vx1-vx2,     cu_sq, f_SE,  f_NW,  omegaDiffusivity,  jTan1-jTan2,       concentration); }
+        q = q_dirNW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[SE ])[kse ] = calcDistributionBC_AD(q, c1o54,  -vx1+vx2,     cu_sq, f_NW,  f_SE,  omegaDiffusivity, -jTan1+jTan2,       concentration); }
+        q = q_dirTE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[BW ])[kbw ] = calcDistributionBC_AD(q, c1o54,   vx1    +vx3, cu_sq, f_TE,  f_BW,  omegaDiffusivity,  jTan1      +jTan3, concentration); }
+        q = q_dirBW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[TE ])[kte ] = calcDistributionBC_AD(q, c1o54,  -vx1    -vx3, cu_sq, f_BW,  f_TE,  omegaDiffusivity, -jTan1      -jTan3, concentration); }
+        q = q_dirBE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[TW ])[ktw ] = calcDistributionBC_AD(q, c1o54,   vx1    -vx3, cu_sq, f_BE,  f_TW,  omegaDiffusivity,  jTan1      -jTan3, concentration); }
+        q = q_dirTW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[BE ])[kbe ] = calcDistributionBC_AD(q, c1o54,  -vx1    +vx3, cu_sq, f_TW,  f_BE,  omegaDiffusivity, -jTan1      +jTan3, concentration); }
+        q = q_dirTN[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[BS ])[kbs ] = calcDistributionBC_AD(q, c1o54,       vx2+vx3, cu_sq, f_TN,  f_BS,  omegaDiffusivity,        jTan2+jTan3, concentration); }
+        q = q_dirBS[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[TN ])[ktn ] = calcDistributionBC_AD(q, c1o54,      -vx2-vx3, cu_sq, f_BS,  f_TN,  omegaDiffusivity,       -jTan2-jTan3, concentration); }
+        q = q_dirBN[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[TS ])[kts ] = calcDistributionBC_AD(q, c1o54,       vx2-vx3, cu_sq, f_BN,  f_TS,  omegaDiffusivity,        jTan2-jTan3, concentration); }
+        q = q_dirTS[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[BN ])[kbn ] = calcDistributionBC_AD(q, c1o54,      -vx2+vx3, cu_sq, f_TS,  f_BN,  omegaDiffusivity,       -jTan2+jTan3, concentration); }
+        q = q_dirTNE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[BSW])[kbsw] = calcDistributionBC_AD(q, c1o216,  vx1+vx2+vx3, cu_sq, f_TNE, f_BSW, omegaDiffusivity,  jTan1+jTan2+jTan3, concentration); }
+        q = q_dirBSW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[TNE])[ktne] = calcDistributionBC_AD(q, c1o216, -vx1-vx2-vx3, cu_sq, f_BSW, f_TNE, omegaDiffusivity, -jTan1-jTan2-jTan3, concentration); }
+        q = q_dirBNE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[TSW])[ktsw] = calcDistributionBC_AD(q, c1o216,  vx1+vx2-vx3, cu_sq, f_BNE, f_TSW, omegaDiffusivity,  jTan1+jTan2-jTan3, concentration); }
+        q = q_dirTSW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[BNE])[kbne] = calcDistributionBC_AD(q, c1o216, -vx1-vx2+vx3, cu_sq, f_TSW, f_BNE, omegaDiffusivity, -jTan1-jTan2+jTan3, concentration); }
+        q = q_dirTSE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[BNW])[kbnw] = calcDistributionBC_AD(q, c1o216,  vx1-vx2+vx3, cu_sq, f_TSE, f_BNW, omegaDiffusivity,  jTan1-jTan2+jTan3, concentration); }
+        q = q_dirBNW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[TSE])[ktse] = calcDistributionBC_AD(q, c1o216, -vx1+vx2-vx3, cu_sq, f_BNW, f_TSE, omegaDiffusivity, -jTan1+jTan2-jTan3, concentration); }
+        q = q_dirBSE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[TNW])[ktnw] = calcDistributionBC_AD(q, c1o216,  vx1-vx2-vx3, cu_sq, f_BSE, f_TNW, omegaDiffusivity,  jTan1-jTan2-jTan3, concentration); }
+        q = q_dirTNW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[BSE])[kbse] = calcDistributionBC_AD(q, c1o216, -vx1+vx2+vx3, cu_sq, f_TNW, f_BSE, omegaDiffusivity, -jTan1+jTan2+jTan3, concentration); }
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BCsAdvectionDiffusion27.cu b/src/gpu/VirtualFluids_GPU/GPU/BCsAdvectionDiffusion27.cu
deleted file mode 100644
index b1fb3456117f7dd65de5439fd6b987a7d984c92e..0000000000000000000000000000000000000000
--- a/src/gpu/VirtualFluids_GPU/GPU/BCsAdvectionDiffusion27.cu
+++ /dev/null
@@ -1,527 +0,0 @@
-//=======================================================================================
-// ____          ____    __    ______     __________   __      __       __        __
-// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
-//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
-//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
-//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
-//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
-//      \    \  |    |   ________________________________________________________________
-//       \    \ |    |  |  ______________________________________________________________|
-//        \    \|    |  |  |         __          __     __     __     ______      _______
-//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
-//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
-//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
-//
-//  This file is part of VirtualFluids. VirtualFluids is free software: you can
-//  redistribute it and/or modify it under the terms of the GNU General Public
-//  License as published by the Free Software Foundation, either version 3 of
-//  the License, or (at your option) any later version.
-//
-//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
-//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-//  for more details.
-//
-//  You should have received a copy of the GNU General Public License along
-//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file AdvectionDiffusion27chim.cu
-//! \ingroup GPU
-//! \author Martin Schoenherr
-//=======================================================================================
-/* Device code */
-#include "LBM/LB.h"
-#include "LBM/D3Q27.h"
-#include <lbm/constants/NumericConstants.h>
-
-using namespace vf::lbm::constant;
-
-////////////////////////////////////////////////////////////////////////////////
-//! \brief forward chimera transformation \ref forwardInverseChimeraWithK
-//! Transformation from distributions to central moments according to Eq. (6)-(14) in \ref
-//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
-//! Modified for lower round-off errors.
-inline __device__ void forwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho) {
-	real m2 = mfa + mfc;
-	real m1 = mfc - mfa;
-	real m0 = m2 + mfb;
-	mfa     = m0;
-	m0     *= Kinverse;
-	m0     += oneMinusRho;
-	mfb     = (m1*Kinverse - m0 * vv) * K;
-	mfc     = ((m2 - c2o1*	m1 * vv)*Kinverse + v2 * m0) * K;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//! \brief backward chimera transformation \ref backwardInverseChimeraWithK
-//! Transformation from central moments to distributions according to Eq. (57)-(65) in \ref
-//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
-//! Modified for lower round-off errors.
-inline __device__ void backwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho) {
-	real m0 = (((mfc - mfb) * c1o2 + mfb *  vv)*Kinverse + (mfa*Kinverse + oneMinusRho) * (v2 - vv) * c1o2) * K;
-	real m1 = (((mfa - mfc) - c2o1 * mfb *  vv)*Kinverse + (mfa*Kinverse + oneMinusRho) * (-v2)) * K;
-	mfc     = (((mfc + mfb) * c1o2 + mfb *  vv)*Kinverse + (mfa*Kinverse + oneMinusRho) * (v2 + vv) * c1o2) * K;
-	mfa     = m0;
-	mfb     = m1;
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-//! \brief forward chimera transformation \ref forwardChimera
-//! - Chimera transform from distributions to central moments as defined in Eq. (43)-(45) in \ref
-//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
-inline __device__ void forwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2) {
-	real m1 = (mfa + mfc) + mfb;
-	real m2 = mfc - mfa;
-	mfc     = (mfc + mfa) + (v2*m1 - c2o1*vv*m2);
-	mfb     = m2 - vv*m1;
-	mfa     = m1;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-//! \brief backward chimera transformation \ref backwardChimera
-//! - Chimera transform from  central moments to distributions as defined in Eq. (88)-(96) in \ref
-//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
-inline __device__ void backwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2) {
-	real ma = (mfc + mfa*(v2 - vv))*c1o2 + mfb*(vv - c1o2);
-	real mb = ((mfa - mfc) - mfa*v2) - c2o1*mfb*vv;
-	mfc     = (mfc + mfa*(v2 + vv))*c1o2 + mfb*(vv + c1o2);
-	mfb     = mb;
-	mfa     = ma;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-inline __device__ real calcDistributionBC_AD_interpol(real q, real weight, real v, real v_sq, real f, real finf, real omegaD, real jTangential, real concentration) {
-    real feq = weight * concentration * (c1o1 + c3o1 * v + c9o2 * v * v * concentration - v_sq * concentration);
-    return (c1o1 - q) / (c1o1 + q) * ((f - feq * omegaD) / (c1o1 - omegaD)) + (q * (f + finf) - c6o1 * weight * (jTangential)) / (c1o1 + q);
-}
-////////////////////////////////////////////////////////////////////////////////
-inline __device__ real calcDistributionBC_AD(real q, real weight, real v, real v_sq, real f, real finf, real omegaD, real jTangential, real concentration) {
-    return f - c6o1 * weight * jTangential;
-}
-
-
-// has to be excecuted before Fluid BCs
-//////////////////////////////////////////////////////////////////////////////
-extern "C" __global__ void AD_SlipVelDeviceComp(
-    real *NormalX,
-    real *NormalY,
-    real *NormalZ,
-    real *distributions,
-    real *distributionsAD,
-    int *QindexArray,
-    real *Qarrays,
-    uint numberOfQs,
-    real omegaD,
-    uint* neighborX,
-    uint* neighborY,
-    uint* neighborZ,
-    uint size_Mat,
-    bool isEvenTimestep)
-{
-    Distributions27 D;
-    if (isEvenTimestep)
-    {
-        D.f[dirE   ] = &distributions[dirE    * size_Mat];
-        D.f[dirW   ] = &distributions[dirW    * size_Mat];
-        D.f[dirN   ] = &distributions[dirN    * size_Mat];
-        D.f[dirS   ] = &distributions[dirS    * size_Mat];
-        D.f[dirT   ] = &distributions[dirT    * size_Mat];
-        D.f[dirB   ] = &distributions[dirB    * size_Mat];
-        D.f[dirNE  ] = &distributions[dirNE   * size_Mat];
-        D.f[dirSW  ] = &distributions[dirSW   * size_Mat];
-        D.f[dirSE  ] = &distributions[dirSE   * size_Mat];
-        D.f[dirNW  ] = &distributions[dirNW   * size_Mat];
-        D.f[dirTE  ] = &distributions[dirTE   * size_Mat];
-        D.f[dirBW  ] = &distributions[dirBW   * size_Mat];
-        D.f[dirBE  ] = &distributions[dirBE   * size_Mat];
-        D.f[dirTW  ] = &distributions[dirTW   * size_Mat];
-        D.f[dirTN  ] = &distributions[dirTN   * size_Mat];
-        D.f[dirBS  ] = &distributions[dirBS   * size_Mat];
-        D.f[dirBN  ] = &distributions[dirBN   * size_Mat];
-        D.f[dirTS  ] = &distributions[dirTS   * size_Mat];
-        D.f[dirREST] = &distributions[dirREST * size_Mat];
-        D.f[dirTNE ] = &distributions[dirTNE  * size_Mat];
-        D.f[dirTSW ] = &distributions[dirTSW  * size_Mat];
-        D.f[dirTSE ] = &distributions[dirTSE  * size_Mat];
-        D.f[dirTNW ] = &distributions[dirTNW  * size_Mat];
-        D.f[dirBNE ] = &distributions[dirBNE  * size_Mat];
-        D.f[dirBSW ] = &distributions[dirBSW  * size_Mat];
-        D.f[dirBSE ] = &distributions[dirBSE  * size_Mat];
-        D.f[dirBNW ] = &distributions[dirBNW  * size_Mat];
-    }
-    else
-    {
-        D.f[dirW   ] = &distributions[dirE    * size_Mat];
-        D.f[dirE   ] = &distributions[dirW    * size_Mat];
-        D.f[dirS   ] = &distributions[dirN    * size_Mat];
-        D.f[dirN   ] = &distributions[dirS    * size_Mat];
-        D.f[dirB   ] = &distributions[dirT    * size_Mat];
-        D.f[dirT   ] = &distributions[dirB    * size_Mat];
-        D.f[dirSW  ] = &distributions[dirNE   * size_Mat];
-        D.f[dirNE  ] = &distributions[dirSW   * size_Mat];
-        D.f[dirNW  ] = &distributions[dirSE   * size_Mat];
-        D.f[dirSE  ] = &distributions[dirNW   * size_Mat];
-        D.f[dirBW  ] = &distributions[dirTE   * size_Mat];
-        D.f[dirTE  ] = &distributions[dirBW   * size_Mat];
-        D.f[dirTW  ] = &distributions[dirBE   * size_Mat];
-        D.f[dirBE  ] = &distributions[dirTW   * size_Mat];
-        D.f[dirBS  ] = &distributions[dirTN   * size_Mat];
-        D.f[dirTN  ] = &distributions[dirBS   * size_Mat];
-        D.f[dirTS  ] = &distributions[dirBN   * size_Mat];
-        D.f[dirBN  ] = &distributions[dirTS   * size_Mat];
-        D.f[dirREST] = &distributions[dirREST * size_Mat];
-        D.f[dirTNE ] = &distributions[dirBSW  * size_Mat];
-        D.f[dirTSW ] = &distributions[dirBNE  * size_Mat];
-        D.f[dirTSE ] = &distributions[dirBNW  * size_Mat];
-        D.f[dirTNW ] = &distributions[dirBSE  * size_Mat];
-        D.f[dirBNE ] = &distributions[dirTSW  * size_Mat];
-        D.f[dirBSW ] = &distributions[dirTNE  * size_Mat];
-        D.f[dirBSE ] = &distributions[dirTNW  * size_Mat];
-        D.f[dirBNW ] = &distributions[dirTSE  * size_Mat];
-    }
-    ////////////////////////////////////////////////////////////////////////////////
-    Distributions27 DAD;
-    if (isEvenTimestep)
-    {
-        DAD.f[dirE   ] = &distributionsAD[dirE    * size_Mat];
-        DAD.f[dirW   ] = &distributionsAD[dirW    * size_Mat];
-        DAD.f[dirN   ] = &distributionsAD[dirN    * size_Mat];
-        DAD.f[dirS   ] = &distributionsAD[dirS    * size_Mat];
-        DAD.f[dirT   ] = &distributionsAD[dirT    * size_Mat];
-        DAD.f[dirB   ] = &distributionsAD[dirB    * size_Mat];
-        DAD.f[dirNE  ] = &distributionsAD[dirNE   * size_Mat];
-        DAD.f[dirSW  ] = &distributionsAD[dirSW   * size_Mat];
-        DAD.f[dirSE  ] = &distributionsAD[dirSE   * size_Mat];
-        DAD.f[dirNW  ] = &distributionsAD[dirNW   * size_Mat];
-        DAD.f[dirTE  ] = &distributionsAD[dirTE   * size_Mat];
-        DAD.f[dirBW  ] = &distributionsAD[dirBW   * size_Mat];
-        DAD.f[dirBE  ] = &distributionsAD[dirBE   * size_Mat];
-        DAD.f[dirTW  ] = &distributionsAD[dirTW   * size_Mat];
-        DAD.f[dirTN  ] = &distributionsAD[dirTN   * size_Mat];
-        DAD.f[dirBS  ] = &distributionsAD[dirBS   * size_Mat];
-        DAD.f[dirBN  ] = &distributionsAD[dirBN   * size_Mat];
-        DAD.f[dirTS  ] = &distributionsAD[dirTS   * size_Mat];
-        DAD.f[dirREST] = &distributionsAD[dirREST * size_Mat];
-        DAD.f[dirTNE ] = &distributionsAD[dirTNE  * size_Mat];
-        DAD.f[dirTSW ] = &distributionsAD[dirTSW  * size_Mat];
-        DAD.f[dirTSE ] = &distributionsAD[dirTSE  * size_Mat];
-        DAD.f[dirTNW ] = &distributionsAD[dirTNW  * size_Mat];
-        DAD.f[dirBNE ] = &distributionsAD[dirBNE  * size_Mat];
-        DAD.f[dirBSW ] = &distributionsAD[dirBSW  * size_Mat];
-        DAD.f[dirBSE ] = &distributionsAD[dirBSE  * size_Mat];
-        DAD.f[dirBNW ] = &distributionsAD[dirBNW  * size_Mat];
-    }
-    else
-    {
-        DAD.f[dirW   ] = &distributionsAD[dirE    * size_Mat];
-        DAD.f[dirE   ] = &distributionsAD[dirW    * size_Mat];
-        DAD.f[dirS   ] = &distributionsAD[dirN    * size_Mat];
-        DAD.f[dirN   ] = &distributionsAD[dirS    * size_Mat];
-        DAD.f[dirB   ] = &distributionsAD[dirT    * size_Mat];
-        DAD.f[dirT   ] = &distributionsAD[dirB    * size_Mat];
-        DAD.f[dirSW  ] = &distributionsAD[dirNE   * size_Mat];
-        DAD.f[dirNE  ] = &distributionsAD[dirSW   * size_Mat];
-        DAD.f[dirNW  ] = &distributionsAD[dirSE   * size_Mat];
-        DAD.f[dirSE  ] = &distributionsAD[dirNW   * size_Mat];
-        DAD.f[dirBW  ] = &distributionsAD[dirTE   * size_Mat];
-        DAD.f[dirTE  ] = &distributionsAD[dirBW   * size_Mat];
-        DAD.f[dirTW  ] = &distributionsAD[dirBE   * size_Mat];
-        DAD.f[dirBE  ] = &distributionsAD[dirTW   * size_Mat];
-        DAD.f[dirBS  ] = &distributionsAD[dirTN   * size_Mat];
-        DAD.f[dirTN  ] = &distributionsAD[dirBS   * size_Mat];
-        DAD.f[dirTS  ] = &distributionsAD[dirBN   * size_Mat];
-        DAD.f[dirBN  ] = &distributionsAD[dirTS   * size_Mat];
-        DAD.f[dirREST] = &distributionsAD[dirREST * size_Mat];
-        DAD.f[dirTNE ] = &distributionsAD[dirBSW  * size_Mat];
-        DAD.f[dirTSW ] = &distributionsAD[dirBNE  * size_Mat];
-        DAD.f[dirTSE ] = &distributionsAD[dirBNW  * size_Mat];
-        DAD.f[dirTNW ] = &distributionsAD[dirBSE  * size_Mat];
-        DAD.f[dirBNE ] = &distributionsAD[dirTSW  * size_Mat];
-        DAD.f[dirBSW ] = &distributionsAD[dirTNE  * size_Mat];
-        DAD.f[dirBSE ] = &distributionsAD[dirTNW  * size_Mat];
-        DAD.f[dirBNW ] = &distributionsAD[dirTSE  * size_Mat];
-    }
-    ////////////////////////////////////////////////////////////////////////////////
-    const unsigned  x = threadIdx.x;  // Globaler x-Index
-    const unsigned  y = blockIdx.x;   // Globaler y-Index
-    const unsigned  z = blockIdx.y;   // Globaler z-Index
-
-    const unsigned nx = blockDim.x;
-    const unsigned ny = gridDim.x;
-
-    const unsigned k = nx * (ny * z + y) + x;
-    //////////////////////////////////////////////////////////////////////////
-
-    if (k < numberOfQs)
-    {
-        ////////////////////////////////////////////////////////////////////////////////
-        real NormX = NormalX[k];
-        real NormY = NormalY[k];
-        real NormZ = NormalZ[k];
-        ////////////////////////////////////////////////////////////////////////////////
-        real* q_dirE, * q_dirW, * q_dirN, * q_dirS, * q_dirT, * q_dirB,
-            * q_dirNE, * q_dirSW, * q_dirSE, * q_dirNW, * q_dirTE, * q_dirBW,
-            * q_dirBE, * q_dirTW, * q_dirTN, * q_dirBS, * q_dirBN, * q_dirTS,
-            * q_dirTNE, * q_dirTSW, * q_dirTSE, * q_dirTNW, * q_dirBNE, * q_dirBSW,
-            * q_dirBSE, * q_dirBNW;
-        q_dirE   = &Qarrays[dirE   * numberOfQs];
-        q_dirW   = &Qarrays[dirW   * numberOfQs];
-        q_dirN   = &Qarrays[dirN   * numberOfQs];
-        q_dirS   = &Qarrays[dirS   * numberOfQs];
-        q_dirT   = &Qarrays[dirT   * numberOfQs];
-        q_dirB   = &Qarrays[dirB   * numberOfQs];
-        q_dirNE  = &Qarrays[dirNE  * numberOfQs];
-        q_dirSW  = &Qarrays[dirSW  * numberOfQs];
-        q_dirSE  = &Qarrays[dirSE  * numberOfQs];
-        q_dirNW  = &Qarrays[dirNW  * numberOfQs];
-        q_dirTE  = &Qarrays[dirTE  * numberOfQs];
-        q_dirBW  = &Qarrays[dirBW  * numberOfQs];
-        q_dirBE  = &Qarrays[dirBE  * numberOfQs];
-        q_dirTW  = &Qarrays[dirTW  * numberOfQs];
-        q_dirTN  = &Qarrays[dirTN  * numberOfQs];
-        q_dirBS  = &Qarrays[dirBS  * numberOfQs];
-        q_dirBN  = &Qarrays[dirBN  * numberOfQs];
-        q_dirTS  = &Qarrays[dirTS  * numberOfQs];
-        q_dirTNE = &Qarrays[dirTNE * numberOfQs];
-        q_dirTSW = &Qarrays[dirTSW * numberOfQs];
-        q_dirTSE = &Qarrays[dirTSE * numberOfQs];
-        q_dirTNW = &Qarrays[dirTNW * numberOfQs];
-        q_dirBNE = &Qarrays[dirBNE * numberOfQs];
-        q_dirBSW = &Qarrays[dirBSW * numberOfQs];
-        q_dirBSE = &Qarrays[dirBSE * numberOfQs];
-        q_dirBNW = &Qarrays[dirBNW * numberOfQs];
-        ////////////////////////////////////////////////////////////////////////////////
-        //index
-        unsigned int KQK   = QindexArray[k];
-        unsigned int kzero = KQK;
-        unsigned int ke    = KQK;
-        unsigned int kw    = neighborX[KQK];
-        unsigned int kn    = KQK;
-        unsigned int ks    = neighborY[KQK];
-        unsigned int kt    = KQK;
-        unsigned int kb    = neighborZ[KQK];
-        unsigned int ksw   = neighborY[kw];
-        unsigned int kne   = KQK;
-        unsigned int kse   = ks;
-        unsigned int knw   = kw;
-        unsigned int kbw   = neighborZ[kw];
-        unsigned int kte   = KQK;
-        unsigned int kbe   = kb;
-        unsigned int ktw   = kw;
-        unsigned int kbs   = neighborZ[ks];
-        unsigned int ktn   = KQK;
-        unsigned int kbn   = kb;
-        unsigned int kts   = ks;
-        unsigned int ktse  = ks;
-        unsigned int kbnw  = kbw;
-        unsigned int ktnw  = kw;
-        unsigned int kbse  = kbs;
-        unsigned int ktsw  = ksw;
-        unsigned int kbne  = kb;
-        unsigned int ktne  = KQK;
-        unsigned int kbsw  = neighborZ[ksw];
-        ////////////////////////////////////////////////////////////////////////////////
-        real f_E, f_W, f_N, f_S, f_T, f_B, f_NE, f_SW, f_SE, f_NW, f_TE, f_BW, f_BE,
-            f_TW, f_TN, f_BS, f_BN, f_TS, f_TNE, f_TSW, f_TSE, f_TNW, f_BNE, f_BSW, f_BSE, f_BNW;
-
-        f_W   = (D.f[dirE])[ke];
-        f_E   = (D.f[dirW])[kw];
-        f_S   = (D.f[dirN])[kn];
-        f_N   = (D.f[dirS])[ks];
-        f_B   = (D.f[dirT])[kt];
-        f_T   = (D.f[dirB])[kb];
-        f_SW  = (D.f[dirNE])[kne];
-        f_NE  = (D.f[dirSW])[ksw];
-        f_NW  = (D.f[dirSE])[kse];
-        f_SE  = (D.f[dirNW])[knw];
-        f_BW  = (D.f[dirTE])[kte];
-        f_TE  = (D.f[dirBW])[kbw];
-        f_TW  = (D.f[dirBE])[kbe];
-        f_BE  = (D.f[dirTW])[ktw];
-        f_BS  = (D.f[dirTN])[ktn];
-        f_TN  = (D.f[dirBS])[kbs];
-        f_TS  = (D.f[dirBN])[kbn];
-        f_BN  = (D.f[dirTS])[kts];
-        f_BSW = (D.f[dirTNE])[ktne];
-        f_BNE = (D.f[dirTSW])[ktsw];
-        f_BNW = (D.f[dirTSE])[ktse];
-        f_BSE = (D.f[dirTNW])[ktnw];
-        f_TSW = (D.f[dirBNE])[kbne];
-        f_TNE = (D.f[dirBSW])[kbsw];
-        f_TNW = (D.f[dirBSE])[kbse];
-        f_TSE = (D.f[dirBNW])[kbnw];
-        ////////////////////////////////////////////////////////////////////////////////
-        real vx1, vx2, vx3, drho, q;
-        drho = f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
-            f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW +
-            f_T + f_B + f_N + f_S + f_E + f_W + ((D.f[dirREST])[kzero]);
-
-        vx1 = (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
-            ((f_BE - f_TW) + (f_TE - f_BW)) + ((f_SE - f_NW) + (f_NE - f_SW)) +
-            (f_E - f_W)) / (c1o1 + drho);
-
-
-        vx2 = ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
-            ((f_BN - f_TS) + (f_TN - f_BS)) + (-(f_SE - f_NW) + (f_NE - f_SW)) +
-            (f_N - f_S)) / (c1o1 + drho);
-
-        vx3 = (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
-            (-(f_BN - f_TS) + (f_TN - f_BS)) + ((f_TE - f_BW) - (f_BE - f_TW)) +
-            (f_T - f_B)) / (c1o1 + drho);
-
-        real cu_sq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3) * (c1o1 + drho);
-
-        ////////////////////////////////////////////////////////////////////////////////
-        f_W   = (DAD.f[dirE])[ke];
-        f_E   = (DAD.f[dirW])[kw];
-        f_S   = (DAD.f[dirN])[kn];
-        f_N   = (DAD.f[dirS])[ks];
-        f_B   = (DAD.f[dirT])[kt];
-        f_T   = (DAD.f[dirB])[kb];
-        f_SW  = (DAD.f[dirNE])[kne];
-        f_NE  = (DAD.f[dirSW])[ksw];
-        f_NW  = (DAD.f[dirSE])[kse];
-        f_SE  = (DAD.f[dirNW])[knw];
-        f_BW  = (DAD.f[dirTE])[kte];
-        f_TE  = (DAD.f[dirBW])[kbw];
-        f_TW  = (DAD.f[dirBE])[kbe];
-        f_BE  = (DAD.f[dirTW])[ktw];
-        f_BS  = (DAD.f[dirTN])[ktn];
-        f_TN  = (DAD.f[dirBS])[kbs];
-        f_TS  = (DAD.f[dirBN])[kbn];
-        f_BN  = (DAD.f[dirTS])[kts];
-        f_BSW = (DAD.f[dirTNE])[ktne];
-        f_BNE = (DAD.f[dirTSW])[ktsw];
-        f_BNW = (DAD.f[dirTSE])[ktse];
-        f_BSE = (DAD.f[dirTNW])[ktnw];
-        f_TSW = (DAD.f[dirBNE])[kbne];
-        f_TNE = (DAD.f[dirBSW])[kbsw];
-        f_TNW = (DAD.f[dirBSE])[kbse];
-        f_TSE = (DAD.f[dirBNW])[kbnw];
-        //////////////////////////////////////////////////////////////////////////
-        if (!isEvenTimestep)
-        {
-            DAD.f[dirE   ] = &distributionsAD[dirE    * size_Mat];
-            DAD.f[dirW   ] = &distributionsAD[dirW    * size_Mat];
-            DAD.f[dirN   ] = &distributionsAD[dirN    * size_Mat];
-            DAD.f[dirS   ] = &distributionsAD[dirS    * size_Mat];
-            DAD.f[dirT   ] = &distributionsAD[dirT    * size_Mat];
-            DAD.f[dirB   ] = &distributionsAD[dirB    * size_Mat];
-            DAD.f[dirNE  ] = &distributionsAD[dirNE   * size_Mat];
-            DAD.f[dirSW  ] = &distributionsAD[dirSW   * size_Mat];
-            DAD.f[dirSE  ] = &distributionsAD[dirSE   * size_Mat];
-            DAD.f[dirNW  ] = &distributionsAD[dirNW   * size_Mat];
-            DAD.f[dirTE  ] = &distributionsAD[dirTE   * size_Mat];
-            DAD.f[dirBW  ] = &distributionsAD[dirBW   * size_Mat];
-            DAD.f[dirBE  ] = &distributionsAD[dirBE   * size_Mat];
-            DAD.f[dirTW  ] = &distributionsAD[dirTW   * size_Mat];
-            DAD.f[dirTN  ] = &distributionsAD[dirTN   * size_Mat];
-            DAD.f[dirBS  ] = &distributionsAD[dirBS   * size_Mat];
-            DAD.f[dirBN  ] = &distributionsAD[dirBN   * size_Mat];
-            DAD.f[dirTS  ] = &distributionsAD[dirTS   * size_Mat];
-            DAD.f[dirREST] = &distributionsAD[dirREST * size_Mat];
-            DAD.f[dirTNE ] = &distributionsAD[dirTNE  * size_Mat];
-            DAD.f[dirTSW ] = &distributionsAD[dirTSW  * size_Mat];
-            DAD.f[dirTSE ] = &distributionsAD[dirTSE  * size_Mat];
-            DAD.f[dirTNW ] = &distributionsAD[dirTNW  * size_Mat];
-            DAD.f[dirBNE ] = &distributionsAD[dirBNE  * size_Mat];
-            DAD.f[dirBSW ] = &distributionsAD[dirBSW  * size_Mat];
-            DAD.f[dirBSE ] = &distributionsAD[dirBSE  * size_Mat];
-            DAD.f[dirBNW ] = &distributionsAD[dirBNW  * size_Mat];
-        }
-        else
-        {
-            DAD.f[dirW   ] = &distributionsAD[dirE    * size_Mat];
-            DAD.f[dirE   ] = &distributionsAD[dirW    * size_Mat];
-            DAD.f[dirS   ] = &distributionsAD[dirN    * size_Mat];
-            DAD.f[dirN   ] = &distributionsAD[dirS    * size_Mat];
-            DAD.f[dirB   ] = &distributionsAD[dirT    * size_Mat];
-            DAD.f[dirT   ] = &distributionsAD[dirB    * size_Mat];
-            DAD.f[dirSW  ] = &distributionsAD[dirNE   * size_Mat];
-            DAD.f[dirNE  ] = &distributionsAD[dirSW   * size_Mat];
-            DAD.f[dirNW  ] = &distributionsAD[dirSE   * size_Mat];
-            DAD.f[dirSE  ] = &distributionsAD[dirNW   * size_Mat];
-            DAD.f[dirBW  ] = &distributionsAD[dirTE   * size_Mat];
-            DAD.f[dirTE  ] = &distributionsAD[dirBW   * size_Mat];
-            DAD.f[dirTW  ] = &distributionsAD[dirBE   * size_Mat];
-            DAD.f[dirBE  ] = &distributionsAD[dirTW   * size_Mat];
-            DAD.f[dirBS  ] = &distributionsAD[dirTN   * size_Mat];
-            DAD.f[dirTN  ] = &distributionsAD[dirBS   * size_Mat];
-            DAD.f[dirTS  ] = &distributionsAD[dirBN   * size_Mat];
-            DAD.f[dirBN  ] = &distributionsAD[dirTS   * size_Mat];
-            DAD.f[dirREST] = &distributionsAD[dirREST * size_Mat];
-            DAD.f[dirTNE ] = &distributionsAD[dirBSW  * size_Mat];
-            DAD.f[dirTSW ] = &distributionsAD[dirBNE  * size_Mat];
-            DAD.f[dirTSE ] = &distributionsAD[dirBNW  * size_Mat];
-            DAD.f[dirTNW ] = &distributionsAD[dirBSE  * size_Mat];
-            DAD.f[dirBNE ] = &distributionsAD[dirTSW  * size_Mat];
-            DAD.f[dirBSW ] = &distributionsAD[dirTNE  * size_Mat];
-            DAD.f[dirBSE ] = &distributionsAD[dirTNW  * size_Mat];
-            DAD.f[dirBNW ] = &distributionsAD[dirTSE  * size_Mat];
-        }
-        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        real concentration =
-            f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
-            f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW +
-            f_T + f_B + f_N + f_S + f_E + f_W + ((D.f[dirREST])[kzero]);
-
-        real jx1 =
-            (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
-            ((f_BE - f_TW) + (f_TE - f_BW)) + ((f_SE - f_NW) + (f_NE - f_SW)) +
-            (f_E - f_W)) - (vx1 * concentration);
-
-        real jx2 =
-            ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
-            ((f_BN - f_TS) + (f_TN - f_BS)) + (-(f_SE - f_NW) + (f_NE - f_SW)) +
-            (f_N - f_S)) - (vx2 * concentration);
-
-        real jx3 =
-            (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
-            (-(f_BN - f_TS) + (f_TN - f_BS)) + ((f_TE - f_BW) - (f_BE - f_TW)) +
-            (f_T - f_B)) - (vx3 * concentration);
-
-        //jx1 *= (c2o1 - omegaD) / (c2o1 - c2o1 * omegaD);
-        //jx2 *= (c2o1 - omegaD) / (c2o1 - c2o1 * omegaD);
-        //jx3 *= (c2o1 - omegaD) / (c2o1 - c2o1 * omegaD);
-
-        real NormJ = jx1 * NormX + jx2 * NormY + jx3 * NormZ;
-
-        real jTan1 = jx1 - NormJ * NormX;
-        real jTan2 = jx2 - NormJ * NormY;
-        real jTan3 = jx3 - NormJ * NormZ;
-
-        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-        q = q_dirE[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirW  ])[kw  ] = calcDistributionBC_AD(q, c2o27,   vx1,         cu_sq, f_E,   f_W,   omegaD,        jTan1,       concentration); }
-        q = q_dirW[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirE  ])[ke  ] = calcDistributionBC_AD(q, c2o27,  -vx1,         cu_sq, f_W,   f_E,   omegaD,       -jTan1,       concentration); }
-        q = q_dirN[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirS  ])[ks  ] = calcDistributionBC_AD(q, c2o27,   vx2,         cu_sq, f_N,   f_S,   omegaD,        jTan2,       concentration); }
-        q = q_dirS[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirN  ])[kn  ] = calcDistributionBC_AD(q, c2o27,  -vx2,         cu_sq, f_S,   f_N,   omegaD,       -jTan2,       concentration); }
-        q = q_dirT[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirB  ])[kb  ] = calcDistributionBC_AD(q, c2o27,   vx3,         cu_sq, f_T,   f_B,   omegaD,        jTan3,       concentration); }
-        q = q_dirB[k];   if (q >= c0o1 && q <= c1o1) { (DAD.f[dirT  ])[kt  ] = calcDistributionBC_AD(q, c2o27,  -vx3,         cu_sq, f_B,   f_T,   omegaD,       -jTan3,       concentration); }
-        q = q_dirNE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirSW ])[ksw ] = calcDistributionBC_AD(q, c1o54,   vx1+vx2,     cu_sq, f_NE,  f_SW,  omegaD,  jTan1+jTan2,       concentration); }
-        q = q_dirSW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirNE ])[kne ] = calcDistributionBC_AD(q, c1o54,  -vx1-vx2,     cu_sq, f_SW,  f_NE,  omegaD, -jTan1-jTan2,       concentration); }
-        q = q_dirSE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirNW ])[knw ] = calcDistributionBC_AD(q, c1o54,   vx1-vx2,     cu_sq, f_SE,  f_NW,  omegaD,  jTan1-jTan2,       concentration); }
-        q = q_dirNW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirSE ])[kse ] = calcDistributionBC_AD(q, c1o54,  -vx1+vx2,     cu_sq, f_NW,  f_SE,  omegaD, -jTan1+jTan2,       concentration); }
-        q = q_dirTE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBW ])[kbw ] = calcDistributionBC_AD(q, c1o54,   vx1    +vx3, cu_sq, f_TE,  f_BW,  omegaD,  jTan1      +jTan3, concentration); }
-        q = q_dirBW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTE ])[kte ] = calcDistributionBC_AD(q, c1o54,  -vx1    -vx3, cu_sq, f_BW,  f_TE,  omegaD, -jTan1      -jTan3, concentration); }
-        q = q_dirBE[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTW ])[ktw ] = calcDistributionBC_AD(q, c1o54,   vx1    -vx3, cu_sq, f_BE,  f_TW,  omegaD,  jTan1      -jTan3, concentration); }
-        q = q_dirTW[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBE ])[kbe ] = calcDistributionBC_AD(q, c1o54,  -vx1    +vx3, cu_sq, f_TW,  f_BE,  omegaD, -jTan1      +jTan3, concentration); }
-        q = q_dirTN[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBS ])[kbs ] = calcDistributionBC_AD(q, c1o54,       vx2+vx3, cu_sq, f_TN,  f_BS,  omegaD,        jTan2+jTan3, concentration); }
-        q = q_dirBS[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTN ])[ktn ] = calcDistributionBC_AD(q, c1o54,      -vx2-vx3, cu_sq, f_BS,  f_TN,  omegaD,       -jTan2-jTan3, concentration); }
-        q = q_dirBN[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTS ])[kts ] = calcDistributionBC_AD(q, c1o54,       vx2-vx3, cu_sq, f_BN,  f_TS,  omegaD,        jTan2-jTan3, concentration); }
-        q = q_dirTS[k];  if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBN ])[kbn ] = calcDistributionBC_AD(q, c1o54,      -vx2+vx3, cu_sq, f_TS,  f_BN,  omegaD,       -jTan2+jTan3, concentration); }
-        q = q_dirTNE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBSW])[kbsw] = calcDistributionBC_AD(q, c1o216,  vx1+vx2+vx3, cu_sq, f_TNE, f_BSW, omegaD,  jTan1+jTan2+jTan3, concentration); }
-        q = q_dirBSW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTNE])[ktne] = calcDistributionBC_AD(q, c1o216, -vx1-vx2-vx3, cu_sq, f_BSW, f_TNE, omegaD, -jTan1-jTan2-jTan3, concentration); }
-        q = q_dirBNE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTSW])[ktsw] = calcDistributionBC_AD(q, c1o216,  vx1+vx2-vx3, cu_sq, f_BNE, f_TSW, omegaD,  jTan1+jTan2-jTan3, concentration); }
-        q = q_dirTSW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBNE])[kbne] = calcDistributionBC_AD(q, c1o216, -vx1-vx2+vx3, cu_sq, f_TSW, f_BNE, omegaD, -jTan1-jTan2+jTan3, concentration); }
-        q = q_dirTSE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBNW])[kbnw] = calcDistributionBC_AD(q, c1o216,  vx1-vx2+vx3, cu_sq, f_TSE, f_BNW, omegaD,  jTan1-jTan2+jTan3, concentration); }
-        q = q_dirBNW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTSE])[ktse] = calcDistributionBC_AD(q, c1o216, -vx1+vx2-vx3, cu_sq, f_BNW, f_TSE, omegaD, -jTan1+jTan2-jTan3, concentration); }
-        q = q_dirBSE[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirTNW])[ktnw] = calcDistributionBC_AD(q, c1o216,  vx1-vx2-vx3, cu_sq, f_BSE, f_TNW, omegaD,  jTan1-jTan2-jTan3, concentration); }
-        q = q_dirTNW[k]; if (q >= c0o1 && q <= c1o1) { (DAD.f[dirBSE])[kbse] = calcDistributionBC_AD(q, c1o216, -vx1+vx2+vx3, cu_sq, f_TNW, f_BSE, omegaD, -jTan1+jTan2+jTan3, concentration); }
-        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/BBDevice27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/BBDevice27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..14d8974c39f606674ba6aa49d5ae55812e78912b
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/BBDevice27.cu
@@ -0,0 +1,180 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BBDevice27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+extern "C" __global__ void BBDevice27(real* distributions, 
+                                     int* subgridDistanceIndices, 
+                                     real* subgridDistances,
+                                     unsigned int numberOfBCnodes, 
+                                     unsigned int* neighborX,
+                                     unsigned int* neighborY,
+                                     unsigned int* neighborZ,
+                                     unsigned int numberOfLBnodes, 
+                                     bool isEvenTimestep)
+{
+   //////////////////////////////////////////////////////////////////////////
+   //! The no-slip boundary condition is executed in the following steps
+   //!
+   ////////////////////////////////////////////////////////////////////////////////
+   //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+   //!
+   const unsigned  x = threadIdx.x;   // global x-index
+   const unsigned  y = blockIdx.x;    // global y-index
+   const unsigned  z = blockIdx.y;    // global z-index
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   //////////////////////////////////////////////////////////////////////////
+   // run for all indices in size of boundary condition (numberOfBCnodes)
+   if(k < numberOfBCnodes)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+      //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local subgrid distances (q's)
+      //!
+      SubgridDistances27 subgridD;
+      getPointersToSubgridDistances(subgridD, subgridDistances, numberOfBCnodes);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      unsigned int indexOfBCnode  = subgridDistanceIndices[k];
+      unsigned int ke   = indexOfBCnode;
+      unsigned int kw   = neighborX[indexOfBCnode];
+      unsigned int kn   = indexOfBCnode;
+      unsigned int ks   = neighborY[indexOfBCnode];
+      unsigned int kt   = indexOfBCnode;
+      unsigned int kb   = neighborZ[indexOfBCnode];
+      unsigned int ksw  = neighborY[kw];
+      unsigned int kne  = indexOfBCnode;
+      unsigned int kse  = ks;
+      unsigned int knw  = kw;
+      unsigned int kbw  = neighborZ[kw];
+      unsigned int kte  = indexOfBCnode;
+      unsigned int kbe  = kb;
+      unsigned int ktw  = kw;
+      unsigned int kbs  = neighborZ[ks];
+      unsigned int ktn  = indexOfBCnode;
+      unsigned int kbn  = kb;
+      unsigned int kts  = ks;
+      unsigned int ktse = ks;
+      unsigned int kbnw = kbw;
+      unsigned int ktnw = kw;
+      unsigned int kbse = kbs;
+      unsigned int ktsw = ksw;
+      unsigned int kbne = kb;
+      unsigned int ktne = indexOfBCnode;
+      unsigned int kbsw = neighborZ[ksw];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions
+      //!
+      real f_W    = (dist.f[E   ])[ke   ];
+      real f_E    = (dist.f[W   ])[kw   ];
+      real f_S    = (dist.f[N   ])[kn   ];
+      real f_N    = (dist.f[S   ])[ks   ];
+      real f_B    = (dist.f[T   ])[kt   ];
+      real f_T    = (dist.f[B   ])[kb   ];
+      real f_SW   = (dist.f[NE  ])[kne  ];
+      real f_NE   = (dist.f[SW  ])[ksw  ];
+      real f_NW   = (dist.f[SE  ])[kse  ];
+      real f_SE   = (dist.f[NW  ])[knw  ];
+      real f_BW   = (dist.f[TE  ])[kte  ];
+      real f_TE   = (dist.f[BW  ])[kbw  ];
+      real f_TW   = (dist.f[BE  ])[kbe  ];
+      real f_BE   = (dist.f[TW  ])[ktw  ];
+      real f_BS   = (dist.f[TN  ])[ktn  ];
+      real f_TN   = (dist.f[BS  ])[kbs  ];
+      real f_TS   = (dist.f[BN  ])[kbn  ];
+      real f_BN   = (dist.f[TS  ])[kts  ];
+      real f_BSW  = (dist.f[TNE ])[ktne ];
+      real f_BNE  = (dist.f[TSW ])[ktsw ];
+      real f_BNW  = (dist.f[TSE ])[ktse ];
+      real f_BSE  = (dist.f[TNW ])[ktnw ];
+      real f_TSW  = (dist.f[BNE ])[kbne ];
+      real f_TNE  = (dist.f[BSW ])[kbsw ];
+      real f_TNW  = (dist.f[BSE ])[kbse ];
+      real f_TSE  = (dist.f[BNW ])[kbnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - change the pointer to write the results in the correct array
+      //!
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, !isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - rewrite distributions if there is a sub-grid distance (q) in same direction
+      real q;
+      q = (subgridD.q[E  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[W  ])[kw  ]=f_E  ;
+      q = (subgridD.q[W  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[E  ])[ke  ]=f_W  ;
+      q = (subgridD.q[N  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[S  ])[ks  ]=f_N  ;
+      q = (subgridD.q[S  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[N  ])[kn  ]=f_S  ;
+      q = (subgridD.q[T  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[B  ])[kb  ]=f_T  ;
+      q = (subgridD.q[B  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[T  ])[kt  ]=f_B  ;
+      q = (subgridD.q[NE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[SW ])[ksw ]=f_NE ;
+      q = (subgridD.q[SW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[NE ])[kne ]=f_SW ;
+      q = (subgridD.q[SE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[NW ])[knw ]=f_SE ;
+      q = (subgridD.q[NW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[SE ])[kse ]=f_NW ;
+      q = (subgridD.q[TE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BW ])[kbw ]=f_TE ;
+      q = (subgridD.q[BW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TE ])[kte ]=f_BW ;
+      q = (subgridD.q[BE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TW ])[ktw ]=f_BE ;
+      q = (subgridD.q[TW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BE ])[kbe ]=f_TW ;
+      q = (subgridD.q[TN ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BS ])[kbs ]=f_TN ;
+      q = (subgridD.q[BS ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TN ])[ktn ]=f_BS ;
+      q = (subgridD.q[BN ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TS ])[kts ]=f_BN ;
+      q = (subgridD.q[TS ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BN ])[kbn ]=f_TS ;
+      q = (subgridD.q[TNE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BSW])[kbsw]=f_TNE;
+      q = (subgridD.q[BSW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TNE])[ktne]=f_BSW;
+      q = (subgridD.q[BNE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TSW])[ktsw]=f_BNE;
+      q = (subgridD.q[TSW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BNE])[kbne]=f_TSW;
+      q = (subgridD.q[TSE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BNW])[kbnw]=f_TSE;
+      q = (subgridD.q[BNW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TSE])[ktse]=f_BNW;
+      q = (subgridD.q[BSE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TNW])[ktnw]=f_BSE;
+      q = (subgridD.q[TNW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BSE])[kbse]=f_TNW;
+   }
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/QDeviceComp27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/QDeviceComp27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..1ac56c4ff6ac52a78183d72528f4c80dee500acf
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/NoSlip/QDeviceComp27.cu
@@ -0,0 +1,384 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file QDeviceComp27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+extern "C" __global__ void QDeviceComp27(
+										 real* distributions, 
+										 int* subgridDistanceIndices, 
+										 real* subgridDistances,
+										 unsigned int numberOfBCnodes, 
+										 real omega, 
+										 unsigned int* neighborX,
+										 unsigned int* neighborY,
+										 unsigned int* neighborZ,
+										 unsigned int numberOfLBnodes, 
+										 bool isEvenTimestep)
+{
+   //////////////////////////////////////////////////////////////////////////
+   //! The velocity boundary condition is executed in the following steps
+   //!
+   ////////////////////////////////////////////////////////////////////////////////
+   //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+   //!
+   const unsigned  x = threadIdx.x;  // global x-index 
+   const unsigned  y = blockIdx.x;   // global y-index 
+   const unsigned  z = blockIdx.y;   // global z-index 
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   if(k < numberOfBCnodes)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+      //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local subgrid distances (q's)
+      //!
+      SubgridDistances27 subgridD;
+      getPointersToSubgridDistances(subgridD, subgridDistances, numberOfBCnodes);
+      
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      unsigned int indexOfBCnode  = subgridDistanceIndices[k];
+      unsigned int kzero= indexOfBCnode;
+      unsigned int ke   = indexOfBCnode;
+      unsigned int kw   = neighborX[indexOfBCnode];
+      unsigned int kn   = indexOfBCnode;
+      unsigned int ks   = neighborY[indexOfBCnode];
+      unsigned int kt   = indexOfBCnode;
+      unsigned int kb   = neighborZ[indexOfBCnode];
+      unsigned int ksw  = neighborY[kw];
+      unsigned int kne  = indexOfBCnode;
+      unsigned int kse  = ks;
+      unsigned int knw  = kw;
+      unsigned int kbw  = neighborZ[kw];
+      unsigned int kte  = indexOfBCnode;
+      unsigned int kbe  = kb;
+      unsigned int ktw  = kw;
+      unsigned int kbs  = neighborZ[ks];
+      unsigned int ktn  = indexOfBCnode;
+      unsigned int kbn  = kb;
+      unsigned int kts  = ks;
+      unsigned int ktse = ks;
+      unsigned int kbnw = kbw;
+      unsigned int ktnw = kw;
+      unsigned int kbse = kbs;
+      unsigned int ktsw = ksw;
+      unsigned int kbne = kb;
+      unsigned int ktne = indexOfBCnode;
+      unsigned int kbsw = neighborZ[ksw];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions
+      //!
+      real f_W    = (dist.f[E   ])[ke   ];
+      real f_E    = (dist.f[W   ])[kw   ];
+      real f_S    = (dist.f[N   ])[kn   ];
+      real f_N    = (dist.f[S   ])[ks   ];
+      real f_B    = (dist.f[T   ])[kt   ];
+      real f_T    = (dist.f[B   ])[kb   ];
+      real f_SW   = (dist.f[NE  ])[kne  ];
+      real f_NE   = (dist.f[SW  ])[ksw  ];
+      real f_NW   = (dist.f[SE  ])[kse  ];
+      real f_SE   = (dist.f[NW  ])[knw  ];
+      real f_BW   = (dist.f[TE  ])[kte  ];
+      real f_TE   = (dist.f[BW  ])[kbw  ];
+      real f_TW   = (dist.f[BE  ])[kbe  ];
+      real f_BE   = (dist.f[TW  ])[ktw  ];
+      real f_BS   = (dist.f[TN  ])[ktn  ];
+      real f_TN   = (dist.f[BS  ])[kbs  ];
+      real f_TS   = (dist.f[BN  ])[kbn  ];
+      real f_BN   = (dist.f[TS  ])[kts  ];
+      real f_BSW  = (dist.f[TNE ])[ktne ];
+      real f_BNE  = (dist.f[TSW ])[ktsw ];
+      real f_BNW  = (dist.f[TSE ])[ktse ];
+      real f_BSE  = (dist.f[TNW ])[ktnw ];
+      real f_TSW  = (dist.f[BNE ])[kbne ];
+      real f_TNE  = (dist.f[BSW ])[kbsw ];
+      real f_TNW  = (dist.f[BSE ])[kbse ];
+      real f_TSE  = (dist.f[BNW ])[kbnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Calculate macroscopic quantities
+      //!
+      real drho = f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
+                  f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW + 
+                  f_T + f_B + f_N + f_S + f_E + f_W + ((dist.f[REST])[kzero]); 
+
+      real vx1  = (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BE - f_TW)   + (f_TE - f_BW))   + ((f_SE - f_NW)   + (f_NE - f_SW)) +
+                   (f_E - f_W)) / (c1o1 + drho);          
+
+      real vx2  = ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BN - f_TS)   + (f_TN - f_BS))    + (-(f_SE - f_NW)  + (f_NE - f_SW)) +
+                   (f_N - f_S)) / (c1o1 + drho); 
+
+      real vx3  = (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
+                   (-(f_BN - f_TS)  + (f_TN - f_BS))   + ((f_TE - f_BW)   - (f_BE - f_TW)) +
+                   (f_T - f_B)) / (c1o1 + drho); 
+
+      real cu_sq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3) * (c1o1 + drho);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - change the pointer to write the results in the correct array
+      //!
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, !isEvenTimestep);
+
+       ////////////////////////////////////////////////////////////////////////////////
+      //! - Update distributions with subgrid distance (q) between zero and one
+      real feq, q, velocityLB;
+      q = (subgridD.q[E])[k];
+      if (q>=c0o1 && q<=c1o1) // only update distribution for q between zero and one
+      {
+         velocityLB = vx1;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[W])[kw] = getInterpolatedDistributionForNoSlipBC(q, f_E, f_W, feq, omega);
+      }
+
+      q = (subgridD.q[W])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1;
+         
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[E])[ke] = getInterpolatedDistributionForNoSlipBC(q, f_W, f_E, feq, omega);
+      }
+
+      q = (subgridD.q[N])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[S])[ks] = getInterpolatedDistributionForNoSlipBC(q, f_N, f_S, feq, omega);
+      }
+
+      q = (subgridD.q[S])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[N])[kn] = getInterpolatedDistributionForNoSlipBC(q, f_S, f_N, feq, omega);
+      }
+
+      q = (subgridD.q[T])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[B])[kb] = getInterpolatedDistributionForNoSlipBC(q, f_T, f_B, feq, omega);
+      }
+
+      q = (subgridD.q[B])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         (dist.f[T])[kt] = getInterpolatedDistributionForNoSlipBC(q, f_B, f_T, feq, omega);
+      }
+
+      q = (subgridD.q[NE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[SW])[ksw] = getInterpolatedDistributionForNoSlipBC(q, f_NE, f_SW, feq, omega);
+      }
+
+      q = (subgridD.q[SW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[NE])[kne] = getInterpolatedDistributionForNoSlipBC(q, f_SW, f_NE, feq, omega);
+      }
+
+      q = (subgridD.q[SE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[NW])[knw] = getInterpolatedDistributionForNoSlipBC(q, f_SE, f_NW, feq, omega);
+      }
+
+      q = (subgridD.q[NW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[SE])[kse] = getInterpolatedDistributionForNoSlipBC(q, f_NW, f_SE, feq, omega);
+      }
+
+      q = (subgridD.q[TE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[BW])[kbw] = getInterpolatedDistributionForNoSlipBC(q, f_TE, f_BW, feq, omega);
+      }
+
+      q = (subgridD.q[BW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[TE])[kte] = getInterpolatedDistributionForNoSlipBC(q, f_BW, f_TE, feq, omega);
+      }
+
+      q = (subgridD.q[BE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[TW])[ktw] = getInterpolatedDistributionForNoSlipBC(q, f_BE, f_TW, feq, omega);
+      }
+
+      q = (subgridD.q[TW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[BE])[kbe] = getInterpolatedDistributionForNoSlipBC(q, f_TW, f_BE, feq, omega);
+      }
+
+      q = (subgridD.q[TN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[BS])[kbs] = getInterpolatedDistributionForNoSlipBC(q, f_TN, f_BS, feq, omega);
+      }
+
+      q = (subgridD.q[BS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[TN])[ktn] = getInterpolatedDistributionForNoSlipBC(q, f_BS, f_TN, feq, omega);
+      }
+
+      q = (subgridD.q[BN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[TS])[kts] = getInterpolatedDistributionForNoSlipBC(q, f_BN, f_TS, feq, omega);
+      }
+
+      q = (subgridD.q[TS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         (dist.f[BN])[kbn] = getInterpolatedDistributionForNoSlipBC(q, f_TS, f_BN, feq, omega);
+      }
+
+      q = (subgridD.q[TNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[BSW])[kbsw] = getInterpolatedDistributionForNoSlipBC(q, f_TNE, f_BSW, feq, omega);
+      }
+
+      q = (subgridD.q[BSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[TNE])[ktne] = getInterpolatedDistributionForNoSlipBC(q, f_BSW, f_TNE, feq, omega);
+      }
+
+      q = (subgridD.q[BNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[TSW])[ktsw] = getInterpolatedDistributionForNoSlipBC(q, f_BNE, f_TSW, feq, omega);
+      }
+
+      q = (subgridD.q[TSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[BNE])[kbne] = getInterpolatedDistributionForNoSlipBC(q, f_TSW, f_BNE, feq, omega);
+      }
+
+      q = (subgridD.q[TSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[BNW])[kbnw] = getInterpolatedDistributionForNoSlipBC(q, f_TSE, f_BNW, feq, omega);
+      }
+
+      q = (subgridD.q[BNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[TSE])[ktse] = getInterpolatedDistributionForNoSlipBC(q, f_BNW, f_TSE, feq, omega);
+      }
+
+      q = (subgridD.q[BSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[TNW])[ktnw] = getInterpolatedDistributionForNoSlipBC(q, f_BSE, f_TNW, feq, omega);
+      }
+
+      q = (subgridD.q[TNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         (dist.f[BSE])[kbse] = getInterpolatedDistributionForNoSlipBC(q, f_TNW, f_BSE, feq, omega);
+      }
+   }
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Pressure/QPressDeviceNEQ27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Pressure/QPressDeviceNEQ27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..90b9083cb663b44a5361a81f4436c39982ac94fa
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Pressure/QPressDeviceNEQ27.cu
@@ -0,0 +1,303 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file QDeviceComp27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+extern "C" __global__ void QPressDeviceNEQ27(real* rhoBC,
+                                             real* distribution, 
+                                             int* bcNodeIndices,
+                                             int* bcNeighborIndices,
+                                             int numberOfBCnodes,
+                                             real omega1, 
+                                             unsigned int* neighborX,
+                                             unsigned int* neighborY,
+                                             unsigned int* neighborZ,
+                                             unsigned int numberOfLBnodes, 
+                                             bool isEvenTimestep)
+{
+   //////////////////////////////////////////////////////////////////////////
+	//! The pressure boundary condition is executed in the following steps
+	//!
+	////////////////////////////////////////////////////////////////////////////////
+	//! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+	//!
+   const unsigned x = threadIdx.x;    // global x-index 
+   const unsigned y = blockIdx.x;     // global y-index 
+   const unsigned z = blockIdx.y;     // global z-index 
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   //////////////////////////////////////////////////////////////////////////
+   //! - Run for all indices in size of boundary condition (numberOfBCnodes)
+   //!
+   if(k < numberOfBCnodes)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+      //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distribution, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local pressure
+      //!
+      real rhoBClocal = rhoBC[k];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      unsigned int KQK  = bcNodeIndices[k];
+      unsigned int kzero= KQK;
+      unsigned int ke   = KQK;
+      unsigned int kw   = neighborX[KQK];
+      unsigned int kn   = KQK;
+      unsigned int ks   = neighborY[KQK];
+      unsigned int kt   = KQK;
+      unsigned int kb   = neighborZ[KQK];
+      unsigned int ksw  = neighborY[kw];
+      unsigned int kne  = KQK;
+      unsigned int kse  = ks;
+      unsigned int knw  = kw;
+      unsigned int kbw  = neighborZ[kw];
+      unsigned int kte  = KQK;
+      unsigned int kbe  = kb;
+      unsigned int ktw  = kw;
+      unsigned int kbs  = neighborZ[ks];
+      unsigned int ktn  = KQK;
+      unsigned int kbn  = kb;
+      unsigned int kts  = ks;
+      unsigned int ktse = ks;
+      unsigned int kbnw = kbw;
+      unsigned int ktnw = kw;
+      unsigned int kbse = kbs;
+      unsigned int ktsw = ksw;
+      unsigned int kbne = kb;
+      unsigned int ktne = KQK;
+      unsigned int kbsw = neighborZ[ksw];
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing) for neighboring node
+      //!
+      unsigned int K1QK  = bcNeighborIndices[k];
+      unsigned int k1zero= K1QK;
+      unsigned int k1e   = K1QK;
+      unsigned int k1w   = neighborX[K1QK];
+      unsigned int k1n   = K1QK;
+      unsigned int k1s   = neighborY[K1QK];
+      unsigned int k1t   = K1QK;
+      unsigned int k1b   = neighborZ[K1QK];
+      unsigned int k1sw  = neighborY[k1w];
+      unsigned int k1ne  = K1QK;
+      unsigned int k1se  = k1s;
+      unsigned int k1nw  = k1w;
+      unsigned int k1bw  = neighborZ[k1w];
+      unsigned int k1te  = K1QK;
+      unsigned int k1be  = k1b;
+      unsigned int k1tw  = k1w;
+      unsigned int k1bs  = neighborZ[k1s];
+      unsigned int k1tn  = K1QK;
+      unsigned int k1bn  = k1b;
+      unsigned int k1ts  = k1s;
+      unsigned int k1tse = k1s;
+      unsigned int k1bnw = k1bw;
+      unsigned int k1tnw = k1w;
+      unsigned int k1bse = k1bs;
+      unsigned int k1tsw = k1sw;
+      unsigned int k1bne = k1b;
+      unsigned int k1tne = K1QK;
+      unsigned int k1bsw = neighborZ[k1sw];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions for neighboring node
+      //!
+      real f1_W    = (dist.f[E   ])[k1e   ];
+      real f1_E    = (dist.f[W   ])[k1w   ];
+      real f1_S    = (dist.f[N   ])[k1n   ];
+      real f1_N    = (dist.f[S   ])[k1s   ];
+      real f1_B    = (dist.f[T   ])[k1t   ];
+      real f1_T    = (dist.f[B   ])[k1b   ];
+      real f1_SW   = (dist.f[NE  ])[k1ne  ];
+      real f1_NE   = (dist.f[SW  ])[k1sw  ];
+      real f1_NW   = (dist.f[SE  ])[k1se  ];
+      real f1_SE   = (dist.f[NW  ])[k1nw  ];
+      real f1_BW   = (dist.f[TE  ])[k1te  ];
+      real f1_TE   = (dist.f[BW  ])[k1bw  ];
+      real f1_TW   = (dist.f[BE  ])[k1be  ];
+      real f1_BE   = (dist.f[TW  ])[k1tw  ];
+      real f1_BS   = (dist.f[TN  ])[k1tn  ];
+      real f1_TN   = (dist.f[BS  ])[k1bs  ];
+      real f1_TS   = (dist.f[BN  ])[k1bn  ];
+      real f1_BN   = (dist.f[TS  ])[k1ts  ];
+      real f1_ZERO = (dist.f[REST])[k1zero];
+      real f1_BSW  = (dist.f[TNE ])[k1tne ];
+      real f1_BNE  = (dist.f[TSW ])[k1tsw ];
+      real f1_BNW  = (dist.f[TSE ])[k1tse ];
+      real f1_BSE  = (dist.f[TNW ])[k1tnw ];
+      real f1_TSW  = (dist.f[BNE ])[k1bne ];
+      real f1_TNE  = (dist.f[BSW ])[k1bsw ];
+      real f1_TNW  = (dist.f[BSE ])[k1bse ];
+      real f1_TSE  = (dist.f[BNW ])[k1bnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Calculate macroscopic quantities (for neighboring node)
+      //!
+      real drho1 = f1_TSE + f1_TNW + f1_TNE + f1_TSW + f1_BSE + f1_BNW + f1_BNE + f1_BSW +
+                   f1_BN + f1_TS + f1_TN + f1_BS + f1_BE + f1_TW + f1_TE + f1_BW + f1_SE + f1_NW + f1_NE + f1_SW + 
+                   f1_T + f1_B + f1_N + f1_S + f1_E + f1_W + ((dist.f[REST])[kzero]); 
+
+      real vx1  = (((f1_TSE - f1_BNW) - (f1_TNW - f1_BSE)) + ((f1_TNE - f1_BSW) - (f1_TSW - f1_BNE)) +
+                   ((f1_BE - f1_TW)   + (f1_TE - f1_BW))   + ((f1_SE - f1_NW)   + (f1_NE - f1_SW)) +
+                   (f1_E - f1_W)) / (c1o1 + drho1);          
+
+      real vx2  = ((-(f1_TSE - f1_BNW) + (f1_TNW - f1_BSE)) + ((f1_TNE - f1_BSW) - (f1_TSW - f1_BNE)) +
+                   ((f1_BN - f1_TS)   + (f1_TN - f1_BS))    + (-(f1_SE - f1_NW)  + (f1_NE - f1_SW)) +
+                   (f1_N - f1_S)) / (c1o1 + drho1); 
+
+      real vx3  = (((f1_TSE - f1_BNW) + (f1_TNW - f1_BSE)) + ((f1_TNE - f1_BSW) + (f1_TSW - f1_BNE)) +
+                   (-(f1_BN - f1_TS)  + (f1_TN - f1_BS))   + ((f1_TE - f1_BW)   - (f1_BE - f1_TW)) +
+                   (f1_T - f1_B)) / (c1o1 + drho1); 
+
+      real cusq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! subtract the equilibrium (eq) to obtain the non-equilibrium (neq) (for neighboring node)
+      //!
+      f1_ZERO  -= c8o27*  (drho1-(drho1+c1o1)*cusq);
+      f1_E     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*( vx1        )+c9o2*( vx1        )*( vx1        )-cusq));
+      f1_W     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*(-vx1        )+c9o2*(-vx1        )*(-vx1        )-cusq));
+      f1_N     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*(    vx2     )+c9o2*(     vx2    )*(     vx2    )-cusq));
+      f1_S     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*(   -vx2     )+c9o2*(    -vx2    )*(    -vx2    )-cusq));
+      f1_T     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*(         vx3)+c9o2*(         vx3)*(         vx3)-cusq));
+      f1_B     -= c2o27*  (drho1+(drho1+c1o1)*(c3o1*(        -vx3)+c9o2*(        -vx3)*(        -vx3)-cusq));
+      f1_NE    -= c1o54*  (drho1+(drho1+c1o1)*(c3o1*( vx1+vx2    )+c9o2*( vx1+vx2    )*( vx1+vx2    )-cusq));
+      f1_SW    -= c1o54*  (drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2    )+c9o2*(-vx1-vx2    )*(-vx1-vx2    )-cusq));
+      f1_SE    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1-vx2    )+c9o2*( vx1-vx2    )*( vx1-vx2    )-cusq));
+      f1_NW    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2    )+c9o2*(-vx1+vx2    )*(-vx1+vx2    )-cusq));
+      f1_TE    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1    +vx3)+c9o2*( vx1    +vx3)*( vx1    +vx3)-cusq));
+      f1_BW    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1    -vx3)+c9o2*(-vx1    -vx3)*(-vx1    -vx3)-cusq));
+      f1_BE    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1    -vx3)+c9o2*( vx1    -vx3)*( vx1    -vx3)-cusq));
+      f1_TW    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1    +vx3)+c9o2*(-vx1    +vx3)*(-vx1    +vx3)-cusq));
+      f1_TN    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(     vx2+vx3)+c9o2*(     vx2+vx3)*(     vx2+vx3)-cusq));
+      f1_BS    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(    -vx2-vx3)+c9o2*(    -vx2-vx3)*(    -vx2-vx3)-cusq));
+      f1_BN    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(     vx2-vx3)+c9o2*(     vx2-vx3)*(     vx2-vx3)-cusq));
+      f1_TS    -=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(    -vx2+vx3)+c9o2*(    -vx2+vx3)*(    -vx2+vx3)-cusq));
+      f1_TNE   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1+vx2+vx3)+c9o2*( vx1+vx2+vx3)*( vx1+vx2+vx3)-cusq));
+      f1_BSW   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cusq));
+      f1_BNE   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1+vx2-vx3)+c9o2*( vx1+vx2-vx3)*( vx1+vx2-vx3)-cusq));
+      f1_TSW   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cusq));
+      f1_TSE   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1-vx2+vx3)+c9o2*( vx1-vx2+vx3)*( vx1-vx2+vx3)-cusq));
+      f1_BNW   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cusq));
+      f1_BSE   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1-vx2-vx3)+c9o2*( vx1-vx2-vx3)*( vx1-vx2-vx3)-cusq));
+      f1_TNW   -=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cusq));
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! redefine drho1 with rhoBClocal
+      //!
+      drho1 = rhoBClocal;
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! add the equilibrium (eq), which is calculated with rhoBClocal (for neighboring node)
+      //!
+      f1_ZERO  += c8o27*  (drho1-(drho1+c1o1)*cusq);
+      f1_E     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*( vx1        )+c9o2*( vx1        )*( vx1        )-cusq));
+      f1_W     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*(-vx1        )+c9o2*(-vx1        )*(-vx1        )-cusq));
+      f1_N     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*(    vx2     )+c9o2*(     vx2    )*(     vx2    )-cusq));
+      f1_S     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*(   -vx2     )+c9o2*(    -vx2    )*(    -vx2    )-cusq));
+      f1_T     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*(         vx3)+c9o2*(         vx3)*(         vx3)-cusq));
+      f1_B     += c2o27*  (drho1+(drho1+c1o1)*(c3o1*(        -vx3)+c9o2*(        -vx3)*(        -vx3)-cusq));
+      f1_NE    += c1o54*  (drho1+(drho1+c1o1)*(c3o1*( vx1+vx2    )+c9o2*( vx1+vx2    )*( vx1+vx2    )-cusq));
+      f1_SW    += c1o54*  (drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2    )+c9o2*(-vx1-vx2    )*(-vx1-vx2    )-cusq));
+      f1_SE    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1-vx2    )+c9o2*( vx1-vx2    )*( vx1-vx2    )-cusq));
+      f1_NW    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2    )+c9o2*(-vx1+vx2    )*(-vx1+vx2    )-cusq));
+      f1_TE    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1    +vx3)+c9o2*( vx1    +vx3)*( vx1    +vx3)-cusq));
+      f1_BW    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1    -vx3)+c9o2*(-vx1    -vx3)*(-vx1    -vx3)-cusq));
+      f1_BE    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*( vx1    -vx3)+c9o2*( vx1    -vx3)*( vx1    -vx3)-cusq));
+      f1_TW    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(-vx1    +vx3)+c9o2*(-vx1    +vx3)*(-vx1    +vx3)-cusq));
+      f1_TN    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(     vx2+vx3)+c9o2*(     vx2+vx3)*(     vx2+vx3)-cusq));
+      f1_BS    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(    -vx2-vx3)+c9o2*(    -vx2-vx3)*(    -vx2-vx3)-cusq));
+      f1_BN    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(     vx2-vx3)+c9o2*(     vx2-vx3)*(     vx2-vx3)-cusq));
+      f1_TS    +=  c1o54* (drho1+(drho1+c1o1)*(c3o1*(    -vx2+vx3)+c9o2*(    -vx2+vx3)*(    -vx2+vx3)-cusq));
+      f1_TNE   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1+vx2+vx3)+c9o2*( vx1+vx2+vx3)*( vx1+vx2+vx3)-cusq));
+      f1_BSW   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cusq));
+      f1_BNE   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1+vx2-vx3)+c9o2*( vx1+vx2-vx3)*( vx1+vx2-vx3)-cusq));
+      f1_TSW   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cusq));
+      f1_TSE   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1-vx2+vx3)+c9o2*( vx1-vx2+vx3)*( vx1-vx2+vx3)-cusq));
+      f1_BNW   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cusq));
+      f1_BSE   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*( vx1-vx2-vx3)+c9o2*( vx1-vx2-vx3)*( vx1-vx2-vx3)-cusq));
+      f1_TNW   +=  c1o216*(drho1+(drho1+c1o1)*(c3o1*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cusq));
+
+      //////////////////////////////////////////////////////////////////////////
+
+      __syncthreads();
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! write the new distributions to the bc nodes
+      //!
+      (dist.f[E   ])[ke   ] = f1_W   ;
+      (dist.f[W   ])[kw   ] = f1_E   ;
+      (dist.f[N   ])[kn   ] = f1_S   ;
+      (dist.f[S   ])[ks   ] = f1_N   ;
+      (dist.f[T   ])[kt   ] = f1_B   ;
+      (dist.f[B   ])[kb   ] = f1_T   ;
+      (dist.f[NE  ])[kne  ] = f1_SW  ;
+      (dist.f[SW  ])[ksw  ] = f1_NE  ;
+      (dist.f[SE  ])[kse  ] = f1_NW  ;
+      (dist.f[NW  ])[knw  ] = f1_SE  ;
+      (dist.f[TE  ])[kte  ] = f1_BW  ;
+      (dist.f[BW  ])[kbw  ] = f1_TE  ;
+      (dist.f[BE  ])[kbe  ] = f1_TW  ;
+      (dist.f[TW  ])[ktw  ] = f1_BE  ;
+      (dist.f[TN  ])[ktn  ] = f1_BS  ;
+      (dist.f[BS  ])[kbs  ] = f1_TN  ;
+      (dist.f[BN  ])[kbn  ] = f1_TS  ;
+      (dist.f[TS  ])[kts  ] = f1_BN  ;
+      (dist.f[REST])[kzero] = f1_ZERO;
+      (dist.f[TNE ])[ktne ] = f1_BSW ;
+      (dist.f[TSW ])[ktsw ] = f1_BNE ;
+      (dist.f[TSE ])[ktse ] = f1_BNW ;
+      (dist.f[TNW ])[ktnw ] = f1_BSE ;
+      (dist.f[BNE ])[kbne ] = f1_TSW ;
+      (dist.f[BSW ])[kbsw ] = f1_TNE ;
+      (dist.f[BSE ])[kbse ] = f1_TNW ;
+      (dist.f[BNW ])[kbnw ] = f1_TSE ;
+   }
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Slip/QSlipDeviceComp27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Slip/QSlipDeviceComp27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..9d205a9f5fec55b2df80e0c421a67a9a1ef3ce36
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Slip/QSlipDeviceComp27.cu
@@ -0,0 +1,503 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file QSlipDevice27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+//////////////////////////////////////////////////////////////////////////////
+extern "C" __global__ void QSlipDeviceComp27(
+                                    real* distributions, 
+                                    int* subgridDistanceIndices, 
+                                    real* subgridDistances,
+                                    unsigned int numberOfBCnodes,
+                                    real omega, 
+                                    unsigned int* neighborX,
+                                    unsigned int* neighborY,
+                                    unsigned int* neighborZ,
+                                    unsigned int numberOfLBnodes, 
+                                    bool isEvenTimestep)
+{
+   //! The slip boundary condition is executed in the following steps
+   //!
+   ////////////////////////////////////////////////////////////////////////////////
+   //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+   //!
+   const unsigned  x = threadIdx.x;  // global x-index 
+   const unsigned  y = blockIdx.x;   // global y-index 
+   const unsigned  z = blockIdx.y;   // global z-index 
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   if(k < numberOfBCnodes)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+      //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local subgrid distances (q's)
+      //!
+      SubgridDistances27 subgridD;
+      getPointersToSubgridDistances(subgridD, subgridDistances, numberOfBCnodes);
+      
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      unsigned int indexOfBCnode  = subgridDistanceIndices[k];
+      unsigned int kzero= indexOfBCnode;
+      unsigned int ke   = indexOfBCnode;
+      unsigned int kw   = neighborX[indexOfBCnode];
+      unsigned int kn   = indexOfBCnode;
+      unsigned int ks   = neighborY[indexOfBCnode];
+      unsigned int kt   = indexOfBCnode;
+      unsigned int kb   = neighborZ[indexOfBCnode];
+      unsigned int ksw  = neighborY[kw];
+      unsigned int kne  = indexOfBCnode;
+      unsigned int kse  = ks;
+      unsigned int knw  = kw;
+      unsigned int kbw  = neighborZ[kw];
+      unsigned int kte  = indexOfBCnode;
+      unsigned int kbe  = kb;
+      unsigned int ktw  = kw;
+      unsigned int kbs  = neighborZ[ks];
+      unsigned int ktn  = indexOfBCnode;
+      unsigned int kbn  = kb;
+      unsigned int kts  = ks;
+      unsigned int ktse = ks;
+      unsigned int kbnw = kbw;
+      unsigned int ktnw = kw;
+      unsigned int kbse = kbs;
+      unsigned int ktsw = ksw;
+      unsigned int kbne = kb;
+      unsigned int ktne = indexOfBCnode;
+      unsigned int kbsw = neighborZ[ksw];
+      
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions
+      //!
+      real f_W    = (dist.f[E   ])[ke   ];
+      real f_E    = (dist.f[W   ])[kw   ];
+      real f_S    = (dist.f[N   ])[kn   ];
+      real f_N    = (dist.f[S   ])[ks   ];
+      real f_B    = (dist.f[T   ])[kt   ];
+      real f_T    = (dist.f[B   ])[kb   ];
+      real f_SW   = (dist.f[NE  ])[kne  ];
+      real f_NE   = (dist.f[SW  ])[ksw  ];
+      real f_NW   = (dist.f[SE  ])[kse  ];
+      real f_SE   = (dist.f[NW  ])[knw  ];
+      real f_BW   = (dist.f[TE  ])[kte  ];
+      real f_TE   = (dist.f[BW  ])[kbw  ];
+      real f_TW   = (dist.f[BE  ])[kbe  ];
+      real f_BE   = (dist.f[TW  ])[ktw  ];
+      real f_BS   = (dist.f[TN  ])[ktn  ];
+      real f_TN   = (dist.f[BS  ])[kbs  ];
+      real f_TS   = (dist.f[BN  ])[kbn  ];
+      real f_BN   = (dist.f[TS  ])[kts  ];
+      real f_BSW  = (dist.f[TNE ])[ktne ];
+      real f_BNE  = (dist.f[TSW ])[ktsw ];
+      real f_BNW  = (dist.f[TSE ])[ktse ];
+      real f_BSE  = (dist.f[TNW ])[ktnw ];
+      real f_TSW  = (dist.f[BNE ])[kbne ];
+      real f_TNE  = (dist.f[BSW ])[kbsw ];
+      real f_TNW  = (dist.f[BSE ])[kbse ];
+      real f_TSE  = (dist.f[BNW ])[kbnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Calculate macroscopic quantities
+      //!
+      real drho = f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
+                  f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW + 
+                  f_T + f_B + f_N + f_S + f_E + f_W + ((dist.f[REST])[kzero]); 
+
+      real vx1  = (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BE - f_TW)   + (f_TE - f_BW))   + ((f_SE - f_NW)   + (f_NE - f_SW)) +
+                   (f_E - f_W)) / (c1o1 + drho);          
+
+      real vx2  = ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BN - f_TS)   + (f_TN - f_BS))    + (-(f_SE - f_NW)  + (f_NE - f_SW)) +
+                   (f_N - f_S)) / (c1o1 + drho); 
+
+      real vx3  = (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
+                   (-(f_BN - f_TS)  + (f_TN - f_BS))   + ((f_TE - f_BW)   - (f_BE - f_TW)) +
+                   (f_T - f_B)) / (c1o1 + drho); 
+
+      real cu_sq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3) * (c1o1 + drho);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - change the pointer to write the results in the correct array
+      //!
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, !isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Multiply the local velocities by a factor
+      //!
+      real fac = c1o1;//c99o100;
+      real VeloX = fac*vx1;
+      real VeloY = fac*vx2;
+      real VeloZ = fac*vx3;
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Update distributions with subgrid distance (q) between zero and one
+      //!
+      real feq, q;
+
+      bool x = false;
+      bool y = false;
+      bool z = false;
+
+      q = (subgridD.q[E])[k];
+      if (q>=c0o1 && q<=c1o1)  // only update distribution for q between zero and one
+      {
+		  VeloX = c0o1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 x = true;
+         feq=c2o27* (drho+c9o2*( vx1        )*( vx1        ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[W])[kw]=(c1o1-q)/(c1o1+q)*(f_E-f_W+(f_E+f_W-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_E+f_W)-c6o1*c2o27*( VeloX     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[W])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		  VeloX = c0o1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 x = true;
+         feq=c2o27* (drho+c9o2*(-vx1        )*(-vx1        ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[E])[ke]=(c1o1-q)/(c1o1+q)*(f_W-f_E+(f_W+f_E-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_W+f_E)-c6o1*c2o27*(-VeloX     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[N])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		  VeloX = fac*vx1;
+		  VeloY = c0o1;
+	     VeloZ = fac*vx3;
+		 y = true;
+         feq=c2o27* (drho+c9o2*(     vx2    )*(     vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[S])[ks]=(c1o1-q)/(c1o1+q)*(f_N-f_S+(f_N+f_S-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_N+f_S)-c6o1*c2o27*( VeloY     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[S])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+		 VeloY = c0o1;
+	     VeloZ = fac*vx3;
+		 y = true;
+         feq=c2o27* (drho+c9o2*(    -vx2    )*(    -vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[N])[kn]=(c1o1-q)/(c1o1+q)*(f_S-f_N+(f_S+f_N-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_S+f_N)-c6o1*c2o27*(-VeloY     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[T])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+		 VeloZ = c0o1;
+		 z = true;
+         feq=c2o27* (drho+c9o2*(         vx3)*(         vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[B])[kb]=(c1o1-q)/(c1o1+q)*(f_T-f_B+(f_T+f_B-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_T+f_B)-c6o1*c2o27*( VeloZ     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[B])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+		 VeloZ = c0o1;
+		 z = true;
+         feq=c2o27* (drho+c9o2*(        -vx3)*(        -vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[T])[kt]=(c1o1-q)/(c1o1+q)*(f_B-f_T+(f_B+f_T-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_B+f_T)-c6o1*c2o27*(-VeloZ     ))/(c1o1+q) - c2o27 * drho;
+      }
+
+      q = (subgridD.q[NE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+         feq=c1o54* (drho+c9o2*( vx1+vx2    )*( vx1+vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[SW])[ksw]=(c1o1-q)/(c1o1+q)*(f_NE-f_SW+(f_NE+f_SW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_NE+f_SW)-c6o1*c1o54*(VeloX+VeloY))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[SW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+         feq=c1o54* (drho+c9o2*(-vx1-vx2    )*(-vx1-vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[NE])[kne]=(c1o1-q)/(c1o1+q)*(f_SW-f_NE+(f_SW+f_NE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_SW+f_NE)-c6o1*c1o54*(-VeloX-VeloY))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[SE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+         feq=c1o54* (drho+c9o2*( vx1-vx2    )*( vx1-vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[NW])[knw]=(c1o1-q)/(c1o1+q)*(f_SE-f_NW+(f_SE+f_NW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_SE+f_NW)-c6o1*c1o54*( VeloX-VeloY))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[NW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+         feq=c1o54* (drho+c9o2*(-vx1+vx2    )*(-vx1+vx2    ) * (c1o1 + drho)-cu_sq); 
+         (dist.f[SE])[kse]=(c1o1-q)/(c1o1+q)*(f_NW-f_SE+(f_NW+f_SE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_NW+f_SE)-c6o1*c1o54*(-VeloX+VeloY))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[TE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*( vx1    +vx3)*( vx1    +vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BW])[kbw]=(c1o1-q)/(c1o1+q)*(f_TE-f_BW+(f_TE+f_BW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TE+f_BW)-c6o1*c1o54*( VeloX+VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[BW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(-vx1    -vx3)*(-vx1    -vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TE])[kte]=(c1o1-q)/(c1o1+q)*(f_BW-f_TE+(f_BW+f_TE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BW+f_TE)-c6o1*c1o54*(-VeloX-VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[BE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*( vx1    -vx3)*( vx1    -vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TW])[ktw]=(c1o1-q)/(c1o1+q)*(f_BE-f_TW+(f_BE+f_TW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BE+f_TW)-c6o1*c1o54*( VeloX-VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[TW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(-vx1    +vx3)*(-vx1    +vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BE])[kbe]=(c1o1-q)/(c1o1+q)*(f_TW-f_BE+(f_TW+f_BE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TW+f_BE)-c6o1*c1o54*(-VeloX+VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[TN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(     vx2+vx3)*(     vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BS])[kbs]=(c1o1-q)/(c1o1+q)*(f_TN-f_BS+(f_TN+f_BS-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TN+f_BS)-c6o1*c1o54*( VeloY+VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[BS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(    -vx2-vx3)*(    -vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TN])[ktn]=(c1o1-q)/(c1o1+q)*(f_BS-f_TN+(f_BS+f_TN-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BS+f_TN)-c6o1*c1o54*( -VeloY-VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[BN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(     vx2-vx3)*(     vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TS])[kts]=(c1o1-q)/(c1o1+q)*(f_BN-f_TS+(f_BN+f_TS-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BN+f_TS)-c6o1*c1o54*( VeloY-VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[TS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o54* (drho+c9o2*(    -vx2+vx3)*(    -vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BN])[kbn]=(c1o1-q)/(c1o1+q)*(f_TS-f_BN+(f_TS+f_BN-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TS+f_BN)-c6o1*c1o54*( -VeloY+VeloZ))/(c1o1+q) - c1o54 * drho;
+      }
+
+      q = (subgridD.q[TNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*( vx1+vx2+vx3)*( vx1+vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BSW])[kbsw]=(c1o1-q)/(c1o1+q)*(f_TNE-f_BSW+(f_TNE+f_BSW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TNE+f_BSW)-c6o1*c1o216*( VeloX+VeloY+VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[BSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TNE])[ktne]=(c1o1-q)/(c1o1+q)*(f_BSW-f_TNE+(f_BSW+f_TNE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BSW+f_TNE)-c6o1*c1o216*(-VeloX-VeloY-VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[BNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*( vx1+vx2-vx3)*( vx1+vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TSW])[ktsw]=(c1o1-q)/(c1o1+q)*(f_BNE-f_TSW+(f_BNE+f_TSW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BNE+f_TSW)-c6o1*c1o216*( VeloX+VeloY-VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[TSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BNE])[kbne]=(c1o1-q)/(c1o1+q)*(f_TSW-f_BNE+(f_TSW+f_BNE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TSW+f_BNE)-c6o1*c1o216*(-VeloX-VeloY+VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[TSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*( vx1-vx2+vx3)*( vx1-vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BNW])[kbnw]=(c1o1-q)/(c1o1+q)*(f_TSE-f_BNW+(f_TSE+f_BNW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TSE+f_BNW)-c6o1*c1o216*( VeloX-VeloY+VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[BNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TSE])[ktse]=(c1o1-q)/(c1o1+q)*(f_BNW-f_TSE+(f_BNW+f_TSE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BNW+f_TSE)-c6o1*c1o216*(-VeloX+VeloY-VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[BSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*( vx1-vx2-vx3)*( vx1-vx2-vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[TNW])[ktnw]=(c1o1-q)/(c1o1+q)*(f_BSE-f_TNW+(f_BSE+f_TNW-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_BSE+f_TNW)-c6o1*c1o216*( VeloX-VeloY-VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+
+      q = (subgridD.q[TNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+		 VeloX = fac*vx1;
+	     VeloY = fac*vx2;
+	     VeloZ = fac*vx3;
+		 if (x == true) VeloX = c0o1;
+		 if (y == true) VeloY = c0o1;
+		 if (z == true) VeloZ = c0o1;
+         feq=c1o216*(drho+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3) * (c1o1 + drho)-cu_sq); 
+         (dist.f[BSE])[kbse]=(c1o1-q)/(c1o1+q)*(f_TNW-f_BSE+(f_TNW+f_BSE-c2o1*feq*omega)/(c1o1-omega))*c1o2+(q*(f_TNW+f_BSE)-c6o1*c1o216*(-VeloX+VeloY+VeloZ))/(c1o1+q) - c1o216 * drho;
+      }
+   }
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDeviceComp27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDeviceComp27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..c90fec7988d8216541304706b07453b7156e7124
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDeviceComp27.cu
@@ -0,0 +1,424 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file QVelDeviceComp27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+//////////////////////////////////////////////////////////////////////////////
+extern "C" __global__ void QVelDeviceComp27(
+											real* velocityX,
+											real* velocityY,
+											real* velocityZ,
+											real* distributions,
+											int* subgridDistanceIndices,
+											real* subgridDistances,
+											unsigned int numberOfBCnodes,
+											real omega,
+											unsigned int* neighborX,
+											unsigned int* neighborY,
+											unsigned int* neighborZ,
+											unsigned int numberOfLBnodes,
+											bool isEvenTimestep)
+{
+   //////////////////////////////////////////////////////////////////////////
+   //! The velocity boundary condition is executed in the following steps
+   //!
+   ////////////////////////////////////////////////////////////////////////////////
+   //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+   //!
+   const unsigned  x = threadIdx.x;  // global x-index 
+   const unsigned  y = blockIdx.x;   // global y-index 
+   const unsigned  z = blockIdx.y;   // global z-index 
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   //////////////////////////////////////////////////////////////////////////
+   //! - Run for all indices in size of boundary condition (numberOfBCnodes)
+   //!
+   if(k < numberOfBCnodes)
+   {
+      //////////////////////////////////////////////////////////////////////////
+      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+      //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local velocities
+      //!
+      real VeloX = velocityX[k];
+      real VeloY = velocityY[k];
+      real VeloZ = velocityZ[k];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local subgrid distances (q's)
+      //!
+      SubgridDistances27 subgridD;
+      getPointersToSubgridDistances(subgridD, subgridDistances, numberOfBCnodes);
+      
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      unsigned int indexOfBCnode  = subgridDistanceIndices[k];
+      unsigned int kzero= indexOfBCnode;
+      unsigned int ke   = indexOfBCnode;
+      unsigned int kw   = neighborX[indexOfBCnode];
+      unsigned int kn   = indexOfBCnode;
+      unsigned int ks   = neighborY[indexOfBCnode];
+      unsigned int kt   = indexOfBCnode;
+      unsigned int kb   = neighborZ[indexOfBCnode];
+      unsigned int ksw  = neighborY[kw];
+      unsigned int kne  = indexOfBCnode;
+      unsigned int kse  = ks;
+      unsigned int knw  = kw;
+      unsigned int kbw  = neighborZ[kw];
+      unsigned int kte  = indexOfBCnode;
+      unsigned int kbe  = kb;
+      unsigned int ktw  = kw;
+      unsigned int kbs  = neighborZ[ks];
+      unsigned int ktn  = indexOfBCnode;
+      unsigned int kbn  = kb;
+      unsigned int kts  = ks;
+      unsigned int ktse = ks;
+      unsigned int kbnw = kbw;
+      unsigned int ktnw = kw;
+      unsigned int kbse = kbs;
+      unsigned int ktsw = ksw;
+      unsigned int kbne = kb;
+      unsigned int ktne = indexOfBCnode;
+      unsigned int kbsw = neighborZ[ksw];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions
+      //!
+      real f_W    = (dist.f[E   ])[ke   ];
+      real f_E    = (dist.f[W   ])[kw   ];
+      real f_S    = (dist.f[N   ])[kn   ];
+      real f_N    = (dist.f[S   ])[ks   ];
+      real f_B    = (dist.f[T   ])[kt   ];
+      real f_T    = (dist.f[B   ])[kb   ];
+      real f_SW   = (dist.f[NE  ])[kne  ];
+      real f_NE   = (dist.f[SW  ])[ksw  ];
+      real f_NW   = (dist.f[SE  ])[kse  ];
+      real f_SE   = (dist.f[NW  ])[knw  ];
+      real f_BW   = (dist.f[TE  ])[kte  ];
+      real f_TE   = (dist.f[BW  ])[kbw  ];
+      real f_TW   = (dist.f[BE  ])[kbe  ];
+      real f_BE   = (dist.f[TW  ])[ktw  ];
+      real f_BS   = (dist.f[TN  ])[ktn  ];
+      real f_TN   = (dist.f[BS  ])[kbs  ];
+      real f_TS   = (dist.f[BN  ])[kbn  ];
+      real f_BN   = (dist.f[TS  ])[kts  ];
+      real f_BSW  = (dist.f[TNE ])[ktne ];
+      real f_BNE  = (dist.f[TSW ])[ktsw ];
+      real f_BNW  = (dist.f[TSE ])[ktse ];
+      real f_BSE  = (dist.f[TNW ])[ktnw ];
+      real f_TSW  = (dist.f[BNE ])[kbne ];
+      real f_TNE  = (dist.f[BSW ])[kbsw ];
+      real f_TNW  = (dist.f[BSE ])[kbse ];
+      real f_TSE  = (dist.f[BNW ])[kbnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Calculate macroscopic quantities
+      //!
+      real drho = f_TSE + f_TNW + f_TNE + f_TSW + f_BSE + f_BNW + f_BNE + f_BSW +
+                  f_BN + f_TS + f_TN + f_BS + f_BE + f_TW + f_TE + f_BW + f_SE + f_NW + f_NE + f_SW + 
+                  f_T + f_B + f_N + f_S + f_E + f_W + ((dist.f[REST])[kzero]); 
+
+      real vx1  = (((f_TSE - f_BNW) - (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BE - f_TW)   + (f_TE - f_BW))   + ((f_SE - f_NW)   + (f_NE - f_SW)) +
+                   (f_E - f_W)) / (c1o1 + drho);          
+
+      real vx2  = ((-(f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) - (f_TSW - f_BNE)) +
+                   ((f_BN - f_TS)   + (f_TN - f_BS))    + (-(f_SE - f_NW)  + (f_NE - f_SW)) +
+                   (f_N - f_S)) / (c1o1 + drho); 
+
+      real vx3  = (((f_TSE - f_BNW) + (f_TNW - f_BSE)) + ((f_TNE - f_BSW) + (f_TSW - f_BNE)) +
+                   (-(f_BN - f_TS)  + (f_TN - f_BS))   + ((f_TE - f_BW)   - (f_BE - f_TW)) +
+                   (f_T - f_B)) / (c1o1 + drho); 
+
+      real cu_sq = c3o2 * (vx1 * vx1 + vx2 * vx2 + vx3 * vx3) * (c1o1 + drho);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - change the pointer to write the results in the correct array
+      //!
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, !isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Update distributions with subgrid distance (q) between zero and one
+      //!
+      real feq, q, velocityLB, velocityBC;
+      q = (subgridD.q[E])[k];
+      if (q>=c0o1 && q<=c1o1) // only update distribution for q between zero and one
+      {
+         velocityLB = vx1;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = VeloX;
+         (dist.f[W])[kw] = getInterpolatedDistributionForVeloBC(q, f_E, f_W, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[W])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = -VeloX;
+         (dist.f[E])[ke] = getInterpolatedDistributionForVeloBC(q, f_W, f_E, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[N])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = VeloY;
+         (dist.f[S])[ks] = getInterpolatedDistributionForVeloBC(q, f_N, f_S, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[S])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = -VeloY;
+         (dist.f[N])[kn] = getInterpolatedDistributionForVeloBC(q, f_S, f_N, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[T])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = VeloZ;
+         (dist.f[B])[kb] = getInterpolatedDistributionForVeloBC(q, f_T, f_B, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[B])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c2o27);
+         velocityBC = -VeloZ;
+         (dist.f[T])[kt] = getInterpolatedDistributionForVeloBC(q, f_B, f_T, feq, omega, velocityBC, c2o27);
+      }
+
+      q = (subgridD.q[NE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloX + VeloY;
+         (dist.f[SW])[ksw] = getInterpolatedDistributionForVeloBC(q, f_NE, f_SW, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[SW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloX - VeloY;
+         (dist.f[NE])[kne] = getInterpolatedDistributionForVeloBC(q, f_SW, f_NE, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[SE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloX - VeloY;
+         (dist.f[NW])[knw] = getInterpolatedDistributionForVeloBC(q, f_SE, f_NW, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[NW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloX + VeloY;
+         (dist.f[SE])[kse] = getInterpolatedDistributionForVeloBC(q, f_NW, f_SE, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[TE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloX + VeloZ;
+         (dist.f[BW])[kbw] = getInterpolatedDistributionForVeloBC(q, f_TE, f_BW, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[BW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloX - VeloZ;
+         (dist.f[TE])[kte] = getInterpolatedDistributionForVeloBC(q, f_BW, f_TE, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[BE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloX - VeloZ;
+         (dist.f[TW])[ktw] = getInterpolatedDistributionForVeloBC(q, f_BE, f_TW, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[TW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloX + VeloZ;
+         (dist.f[BE])[kbe] = getInterpolatedDistributionForVeloBC(q, f_TW, f_BE, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[TN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloY + VeloZ;
+         (dist.f[BS])[kbs] = getInterpolatedDistributionForVeloBC(q, f_TN, f_BS, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[BS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloY - VeloZ;
+         (dist.f[TN])[ktn] = getInterpolatedDistributionForVeloBC(q, f_BS, f_TN, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[BN])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = VeloY - VeloZ;
+         (dist.f[TS])[kts] = getInterpolatedDistributionForVeloBC(q, f_BN, f_TS, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[TS])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o54);
+         velocityBC = -VeloY + VeloZ;
+         (dist.f[BN])[kbn] = getInterpolatedDistributionForVeloBC(q, f_TS, f_BN, feq, omega, velocityBC, c1o54);
+      }
+
+      q = (subgridD.q[TNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = VeloX + VeloY + VeloZ;
+         (dist.f[BSW])[kbsw] = getInterpolatedDistributionForVeloBC(q, f_TNE, f_BSW, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[BSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = -VeloX - VeloY - VeloZ;
+         (dist.f[TNE])[ktne] = getInterpolatedDistributionForVeloBC(q, f_BSW, f_TNE, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[BNE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 + vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = VeloX + VeloY - VeloZ;
+         (dist.f[TSW])[ktsw] = getInterpolatedDistributionForVeloBC(q, f_BNE, f_TSW, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[TSW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 - vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = -VeloX - VeloY + VeloZ;
+         (dist.f[BNE])[kbne] = getInterpolatedDistributionForVeloBC(q, f_TSW, f_BNE, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[TSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = VeloX - VeloY + VeloZ;
+         (dist.f[BNW])[kbnw] = getInterpolatedDistributionForVeloBC(q, f_TSE, f_BNW, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[BNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = -VeloX + VeloY - VeloZ;
+         (dist.f[TSE])[ktse] = getInterpolatedDistributionForVeloBC(q, f_BNW, f_TSE, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[BSE])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = vx1 - vx2 - vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = VeloX - VeloY - VeloZ;
+         (dist.f[TNW])[ktnw] = getInterpolatedDistributionForVeloBC(q, f_BSE, f_TNW, feq, omega, velocityBC, c1o216);
+      }
+
+      q = (subgridD.q[TNW])[k];
+      if (q>=c0o1 && q<=c1o1)
+      {
+         velocityLB = -vx1 + vx2 + vx3;
+         feq = getEquilibriumForBC(drho, velocityLB, cu_sq, c1o216);
+         velocityBC = -VeloX + VeloY + VeloZ;
+         (dist.f[BSE])[kbse] = getInterpolatedDistributionForVeloBC(q, f_TNW, f_BSE, feq, omega, velocityBC, c1o216);
+      }
+   }
+}
diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDevicePlainBB27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDevicePlainBB27.cu
new file mode 100644
index 0000000000000000000000000000000000000000..ac4b36a2399dd4dd3df3ff28596312358ed10b49
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/Velocity/QVelDevicePlainBB27.cu
@@ -0,0 +1,192 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file QVelDevicePlainBB27.cu
+//! \ingroup BoundaryConditions
+//! \author Martin Schoenherr
+//=======================================================================================
+/* Device code */
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+#include "GPU/KernelUtilities.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+//////////////////////////////////////////////////////////////////////////////
+extern "C" __global__ void QVelDevicePlainBB27(
+   real* velocityX,
+   real* velocityY,
+   real* velocityZ,
+   real* distributions,
+   int* subgridDistanceIndices,
+   real* subgridDistances,
+   uint numberOfBCnodes,
+   uint* neighborX,
+   uint* neighborY,
+   uint* neighborZ,
+   uint numberOfLBnodes,
+   bool isEvenTimestep)
+{
+   //////////////////////////////////////////////////////////////////////////
+   //! The velocity boundary condition is executed in the following steps
+   //!
+   ////////////////////////////////////////////////////////////////////////////////
+   //! - Get node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
+   //!
+   const unsigned  x = threadIdx.x;   // global x-index
+   const unsigned  y = blockIdx.x;    // global y-index
+   const unsigned  z = blockIdx.y;    // global z-index
+
+   const unsigned nx = blockDim.x;
+   const unsigned ny = gridDim.x;
+
+   const unsigned k = nx*(ny*z + y) + x;
+
+   //////////////////////////////////////////////////////////////////////////
+   // run for all indices in size of boundary condition (numberOfBCnodes)
+   if(k < numberOfBCnodes)
+   {
+       //////////////////////////////////////////////////////////////////////////
+       //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
+       //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+       //!
+      Distributions27 dist;
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local velocities
+      //!
+      real VeloX = velocityX[k];
+      real VeloY = velocityY[k];
+      real VeloZ = velocityZ[k];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local subgrid distances (q's)
+      //!
+      SubgridDistances27 subgridD;
+      getPointersToSubgridDistances(subgridD, subgridDistances, numberOfBCnodes);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set neighbor indices (necessary for indirect addressing)
+      //!
+      uint indexOfBCnode = subgridDistanceIndices[k];
+      uint ke   = indexOfBCnode;
+      uint kw   = neighborX[indexOfBCnode];
+      uint kn   = indexOfBCnode;
+      uint ks   = neighborY[indexOfBCnode];
+      uint kt   = indexOfBCnode;
+      uint kb   = neighborZ[indexOfBCnode];
+      uint ksw  = neighborY[kw];
+      uint kne  = indexOfBCnode;
+      uint kse  = ks;
+      uint knw  = kw;
+      uint kbw  = neighborZ[kw];
+      uint kte  = indexOfBCnode;
+      uint kbe  = kb;
+      uint ktw  = kw;
+      uint kbs  = neighborZ[ks];
+      uint ktn  = indexOfBCnode;
+      uint kbn  = kb;
+      uint kts  = ks;
+      uint ktse = ks;
+      uint kbnw = kbw;
+      uint ktnw = kw;
+      uint kbse = kbs;
+      uint ktsw = ksw;
+      uint kbne = kb;
+      uint ktne = indexOfBCnode;
+      uint kbsw = neighborZ[ksw];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - Set local distributions
+      //!
+      real f_W    = (dist.f[E   ])[ke   ];
+      real f_E    = (dist.f[W   ])[kw   ];
+      real f_S    = (dist.f[N   ])[kn   ];
+      real f_N    = (dist.f[S   ])[ks   ];
+      real f_B    = (dist.f[T   ])[kt   ];
+      real f_T    = (dist.f[B   ])[kb   ];
+      real f_SW   = (dist.f[NE  ])[kne  ];
+      real f_NE   = (dist.f[SW  ])[ksw  ];
+      real f_NW   = (dist.f[SE  ])[kse  ];
+      real f_SE   = (dist.f[NW  ])[knw  ];
+      real f_BW   = (dist.f[TE  ])[kte  ];
+      real f_TE   = (dist.f[BW  ])[kbw  ];
+      real f_TW   = (dist.f[BE  ])[kbe  ];
+      real f_BE   = (dist.f[TW  ])[ktw  ];
+      real f_BS   = (dist.f[TN  ])[ktn  ];
+      real f_TN   = (dist.f[BS  ])[kbs  ];
+      real f_TS   = (dist.f[BN  ])[kbn  ];
+      real f_BN   = (dist.f[TS  ])[kts  ];
+      real f_BSW  = (dist.f[TNE ])[ktne ];
+      real f_BNE  = (dist.f[TSW ])[ktsw ];
+      real f_BNW  = (dist.f[TSE ])[ktse ];
+      real f_BSE  = (dist.f[TNW ])[ktnw ];
+      real f_TSW  = (dist.f[BNE ])[kbne ];
+      real f_TNE  = (dist.f[BSW ])[kbsw ];
+      real f_TNW  = (dist.f[BSE ])[kbse ];
+      real f_TSE  = (dist.f[BNW ])[kbnw ];
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - change the pointer to write the results in the correct array
+      //!
+      getPointersToDistributions(dist, distributions, numberOfLBnodes, !isEvenTimestep);
+
+      ////////////////////////////////////////////////////////////////////////////////
+      //! - rewrite distributions if there is a sub-grid distance (q) in same direction
+      real q;
+      q = (subgridD.q[E  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[W  ])[kw  ]=f_E   + c4o9  * (-VeloX);
+      q = (subgridD.q[W  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[E  ])[ke  ]=f_W   + c4o9  * ( VeloX);
+      q = (subgridD.q[N  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[S  ])[ks  ]=f_N   + c4o9  * (-VeloY);
+      q = (subgridD.q[S  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[N  ])[kn  ]=f_S   + c4o9  * ( VeloY);
+      q = (subgridD.q[T  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[B  ])[kb  ]=f_T   + c4o9  * (-VeloZ);
+      q = (subgridD.q[B  ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[T  ])[kt  ]=f_B   + c4o9  * ( VeloZ);
+      q = (subgridD.q[NE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[SW ])[ksw ]=f_NE  + c1o9  * (-VeloX - VeloY);
+      q = (subgridD.q[SW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[NE ])[kne ]=f_SW  + c1o9  * ( VeloX + VeloY);
+      q = (subgridD.q[SE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[NW ])[knw ]=f_SE  + c1o9  * (-VeloX + VeloY);
+      q = (subgridD.q[NW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[SE ])[kse ]=f_NW  + c1o9  * ( VeloX - VeloY);
+      q = (subgridD.q[TE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BW ])[kbw ]=f_TE  + c1o9  * (-VeloX - VeloZ);
+      q = (subgridD.q[BW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TE ])[kte ]=f_BW  + c1o9  * ( VeloX + VeloZ);
+      q = (subgridD.q[BE ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TW ])[ktw ]=f_BE  + c1o9  * (-VeloX + VeloZ);
+      q = (subgridD.q[TW ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BE ])[kbe ]=f_TW  + c1o9  * ( VeloX - VeloZ);
+      q = (subgridD.q[TN ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BS ])[kbs ]=f_TN  + c1o9  * (-VeloY - VeloZ);
+      q = (subgridD.q[BS ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TN ])[ktn ]=f_BS  + c1o9  * ( VeloY + VeloZ);
+      q = (subgridD.q[BN ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TS ])[kts ]=f_BN  + c1o9  * (-VeloY + VeloZ);
+      q = (subgridD.q[TS ])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BN ])[kbn ]=f_TS  + c1o9  * ( VeloY - VeloZ);
+      q = (subgridD.q[TNE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BSW])[kbsw]=f_TNE + c1o36 * (-VeloX - VeloY - VeloZ);
+      q = (subgridD.q[BSW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TNE])[ktne]=f_BSW + c1o36 * ( VeloX + VeloY + VeloZ);
+      q = (subgridD.q[BNE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TSW])[ktsw]=f_BNE + c1o36 * (-VeloX - VeloY + VeloZ);
+      q = (subgridD.q[TSW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BNE])[kbne]=f_TSW + c1o36 * ( VeloX + VeloY - VeloZ);
+      q = (subgridD.q[TSE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BNW])[kbnw]=f_TSE + c1o36 * (-VeloX + VeloY - VeloZ);
+      q = (subgridD.q[BNW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TSE])[ktse]=f_BNW + c1o36 * ( VeloX - VeloY + VeloZ);
+      q = (subgridD.q[BSE])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[TNW])[ktnw]=f_BSE + c1o36 * (-VeloX + VeloY + VeloZ);
+      q = (subgridD.q[TNW])[k];   if (q>=c0o1 && q<=c1o1)    (dist.f[BSE])[kbse]=f_TNW + c1o36 * ( VeloX - VeloY - VeloZ);
+   }
+}
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CalcConc27.cu b/src/gpu/VirtualFluids_GPU/GPU/CalcConc27.cu
index 4067a702a6fdf76e073c1a8c26833d2e338bf227..3e6de7e2545a94591538bb81288f755f4f891c82 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CalcConc27.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/CalcConc27.cu
@@ -32,9 +32,10 @@
 //=======================================================================================
 /* Device code */
 #include "LBM/LB.h"
-#include "LBM/D3Q27.h"
+#include "lbm/constants/D3Q27.h"
 #include <lbm/constants/NumericConstants.h>
 
+using namespace vf::lbm::dir;
 using namespace vf::lbm::constant;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -54,9 +55,9 @@ extern "C" __global__ void CalcConc27(
    ////////////////////////////////////////////////////////////////////////////////
    //! - Get node index coordinates from thredIdx, blockIdx, blockDim and gridDim.
    //!
-   const unsigned  x = threadIdx.x;  // Globaler x-Index
-   const unsigned  y = blockIdx.x;   // Globaler y-Index
-   const unsigned  z = blockIdx.y;   // Globaler z-Index
+   const unsigned  x = threadIdx.x;  // global x-index
+   const unsigned  y = blockIdx.x;   // global y-index
+   const unsigned  z = blockIdx.y;   // global z-index
 
    const unsigned nx = blockDim.x;
    const unsigned ny = gridDim.x;
@@ -75,63 +76,63 @@ extern "C" __global__ void CalcConc27(
       Distributions27 distAD;
       if (isEvenTimestep)
       {
-         distAD.f[dirE   ] = &distributionsAD[dirE   *size_Mat];
-         distAD.f[dirW   ] = &distributionsAD[dirW   *size_Mat];
-         distAD.f[dirN   ] = &distributionsAD[dirN   *size_Mat];
-         distAD.f[dirS   ] = &distributionsAD[dirS   *size_Mat];
-         distAD.f[dirT   ] = &distributionsAD[dirT   *size_Mat];
-         distAD.f[dirB   ] = &distributionsAD[dirB   *size_Mat];
-         distAD.f[dirNE  ] = &distributionsAD[dirNE  *size_Mat];
-         distAD.f[dirSW  ] = &distributionsAD[dirSW  *size_Mat];
-         distAD.f[dirSE  ] = &distributionsAD[dirSE  *size_Mat];
-         distAD.f[dirNW  ] = &distributionsAD[dirNW  *size_Mat];
-         distAD.f[dirTE  ] = &distributionsAD[dirTE  *size_Mat];
-         distAD.f[dirBW  ] = &distributionsAD[dirBW  *size_Mat];
-         distAD.f[dirBE  ] = &distributionsAD[dirBE  *size_Mat];
-         distAD.f[dirTW  ] = &distributionsAD[dirTW  *size_Mat];
-         distAD.f[dirTN  ] = &distributionsAD[dirTN  *size_Mat];
-         distAD.f[dirBS  ] = &distributionsAD[dirBS  *size_Mat];
-         distAD.f[dirBN  ] = &distributionsAD[dirBN  *size_Mat];
-         distAD.f[dirTS  ] = &distributionsAD[dirTS  *size_Mat];
-         distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-         distAD.f[dirTNE ] = &distributionsAD[dirTNE *size_Mat];
-         distAD.f[dirTSW ] = &distributionsAD[dirTSW *size_Mat];
-         distAD.f[dirTSE ] = &distributionsAD[dirTSE *size_Mat];
-         distAD.f[dirTNW ] = &distributionsAD[dirTNW *size_Mat];
-         distAD.f[dirBNE ] = &distributionsAD[dirBNE *size_Mat];
-         distAD.f[dirBSW ] = &distributionsAD[dirBSW *size_Mat];
-         distAD.f[dirBSE ] = &distributionsAD[dirBSE *size_Mat];
-         distAD.f[dirBNW ] = &distributionsAD[dirBNW *size_Mat];
+         distAD.f[E   ] = &distributionsAD[E   *size_Mat];
+         distAD.f[W   ] = &distributionsAD[W   *size_Mat];
+         distAD.f[N   ] = &distributionsAD[N   *size_Mat];
+         distAD.f[S   ] = &distributionsAD[S   *size_Mat];
+         distAD.f[T   ] = &distributionsAD[T   *size_Mat];
+         distAD.f[B   ] = &distributionsAD[B   *size_Mat];
+         distAD.f[NE  ] = &distributionsAD[NE  *size_Mat];
+         distAD.f[SW  ] = &distributionsAD[SW  *size_Mat];
+         distAD.f[SE  ] = &distributionsAD[SE  *size_Mat];
+         distAD.f[NW  ] = &distributionsAD[NW  *size_Mat];
+         distAD.f[TE  ] = &distributionsAD[TE  *size_Mat];
+         distAD.f[BW  ] = &distributionsAD[BW  *size_Mat];
+         distAD.f[BE  ] = &distributionsAD[BE  *size_Mat];
+         distAD.f[TW  ] = &distributionsAD[TW  *size_Mat];
+         distAD.f[TN  ] = &distributionsAD[TN  *size_Mat];
+         distAD.f[BS  ] = &distributionsAD[BS  *size_Mat];
+         distAD.f[BN  ] = &distributionsAD[BN  *size_Mat];
+         distAD.f[TS  ] = &distributionsAD[TS  *size_Mat];
+         distAD.f[REST] = &distributionsAD[REST*size_Mat];
+         distAD.f[TNE ] = &distributionsAD[TNE *size_Mat];
+         distAD.f[TSW ] = &distributionsAD[TSW *size_Mat];
+         distAD.f[TSE ] = &distributionsAD[TSE *size_Mat];
+         distAD.f[TNW ] = &distributionsAD[TNW *size_Mat];
+         distAD.f[BNE ] = &distributionsAD[BNE *size_Mat];
+         distAD.f[BSW ] = &distributionsAD[BSW *size_Mat];
+         distAD.f[BSE ] = &distributionsAD[BSE *size_Mat];
+         distAD.f[BNW ] = &distributionsAD[BNW *size_Mat];
       }
       else
       {
-         distAD.f[dirW   ] = &distributionsAD[dirE   *size_Mat];
-         distAD.f[dirE   ] = &distributionsAD[dirW   *size_Mat];
-         distAD.f[dirS   ] = &distributionsAD[dirN   *size_Mat];
-         distAD.f[dirN   ] = &distributionsAD[dirS   *size_Mat];
-         distAD.f[dirB   ] = &distributionsAD[dirT   *size_Mat];
-         distAD.f[dirT   ] = &distributionsAD[dirB   *size_Mat];
-         distAD.f[dirSW  ] = &distributionsAD[dirNE  *size_Mat];
-         distAD.f[dirNE  ] = &distributionsAD[dirSW  *size_Mat];
-         distAD.f[dirNW  ] = &distributionsAD[dirSE  *size_Mat];
-         distAD.f[dirSE  ] = &distributionsAD[dirNW  *size_Mat];
-         distAD.f[dirBW  ] = &distributionsAD[dirTE  *size_Mat];
-         distAD.f[dirTE  ] = &distributionsAD[dirBW  *size_Mat];
-         distAD.f[dirTW  ] = &distributionsAD[dirBE  *size_Mat];
-         distAD.f[dirBE  ] = &distributionsAD[dirTW  *size_Mat];
-         distAD.f[dirBS  ] = &distributionsAD[dirTN  *size_Mat];
-         distAD.f[dirTN  ] = &distributionsAD[dirBS  *size_Mat];
-         distAD.f[dirTS  ] = &distributionsAD[dirBN  *size_Mat];
-         distAD.f[dirBN  ] = &distributionsAD[dirTS  *size_Mat];
-         distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-         distAD.f[dirTNE ] = &distributionsAD[dirBSW *size_Mat];
-         distAD.f[dirTSW ] = &distributionsAD[dirBNE *size_Mat];
-         distAD.f[dirTSE ] = &distributionsAD[dirBNW *size_Mat];
-         distAD.f[dirTNW ] = &distributionsAD[dirBSE *size_Mat];
-         distAD.f[dirBNE ] = &distributionsAD[dirTSW *size_Mat];
-         distAD.f[dirBSW ] = &distributionsAD[dirTNE *size_Mat];
-         distAD.f[dirBSE ] = &distributionsAD[dirTNW *size_Mat];
-         distAD.f[dirBNW ] = &distributionsAD[dirTSE *size_Mat];
+         distAD.f[W   ] = &distributionsAD[E   *size_Mat];
+         distAD.f[E   ] = &distributionsAD[W   *size_Mat];
+         distAD.f[S   ] = &distributionsAD[N   *size_Mat];
+         distAD.f[N   ] = &distributionsAD[S   *size_Mat];
+         distAD.f[B   ] = &distributionsAD[T   *size_Mat];
+         distAD.f[T   ] = &distributionsAD[B   *size_Mat];
+         distAD.f[SW  ] = &distributionsAD[NE  *size_Mat];
+         distAD.f[NE  ] = &distributionsAD[SW  *size_Mat];
+         distAD.f[NW  ] = &distributionsAD[SE  *size_Mat];
+         distAD.f[SE  ] = &distributionsAD[NW  *size_Mat];
+         distAD.f[BW  ] = &distributionsAD[TE  *size_Mat];
+         distAD.f[TE  ] = &distributionsAD[BW  *size_Mat];
+         distAD.f[TW  ] = &distributionsAD[BE  *size_Mat];
+         distAD.f[BE  ] = &distributionsAD[TW  *size_Mat];
+         distAD.f[BS  ] = &distributionsAD[TN  *size_Mat];
+         distAD.f[TN  ] = &distributionsAD[BS  *size_Mat];
+         distAD.f[TS  ] = &distributionsAD[BN  *size_Mat];
+         distAD.f[BN  ] = &distributionsAD[TS  *size_Mat];
+         distAD.f[REST] = &distributionsAD[REST*size_Mat];
+         distAD.f[TNE ] = &distributionsAD[BSW *size_Mat];
+         distAD.f[TSW ] = &distributionsAD[BNE *size_Mat];
+         distAD.f[TSE ] = &distributionsAD[BNW *size_Mat];
+         distAD.f[TNW ] = &distributionsAD[BSE *size_Mat];
+         distAD.f[BNE ] = &distributionsAD[TSW *size_Mat];
+         distAD.f[BSW ] = &distributionsAD[TNE *size_Mat];
+         distAD.f[BSE ] = &distributionsAD[TNW *size_Mat];
+         distAD.f[BNW ] = &distributionsAD[TSE *size_Mat];
       }
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set neighbor indices (necessary for indirect addressing)
@@ -165,33 +166,33 @@ extern "C" __global__ void CalcConc27(
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set local distributions
 	  //!
-	  real mfcbb = (distAD.f[dirE   ])[ke  ];
-	  real mfabb = (distAD.f[dirW   ])[kw  ];
-	  real mfbcb = (distAD.f[dirN   ])[kn  ];
-	  real mfbab = (distAD.f[dirS   ])[ks  ];
-	  real mfbbc = (distAD.f[dirT   ])[kt  ];
-	  real mfbba = (distAD.f[dirB   ])[kb  ];
-	  real mfccb = (distAD.f[dirNE  ])[kne ];
-	  real mfaab = (distAD.f[dirSW  ])[ksw ];
-	  real mfcab = (distAD.f[dirSE  ])[kse ];
-	  real mfacb = (distAD.f[dirNW  ])[knw ];
-	  real mfcbc = (distAD.f[dirTE  ])[kte ];
-	  real mfaba = (distAD.f[dirBW  ])[kbw ];
-	  real mfcba = (distAD.f[dirBE  ])[kbe ];
-	  real mfabc = (distAD.f[dirTW  ])[ktw ];
-	  real mfbcc = (distAD.f[dirTN  ])[ktn ];
-	  real mfbaa = (distAD.f[dirBS  ])[kbs ];
-	  real mfbca = (distAD.f[dirBN  ])[kbn ];
-	  real mfbac = (distAD.f[dirTS  ])[kts ];
-	  real mfbbb = (distAD.f[dirREST])[k   ];
-	  real mfccc = (distAD.f[dirTNE ])[ktne];
-	  real mfaac = (distAD.f[dirTSW ])[ktsw];
-	  real mfcac = (distAD.f[dirTSE ])[ktse];
-	  real mfacc = (distAD.f[dirTNW ])[ktnw];
-	  real mfcca = (distAD.f[dirBNE ])[kbne];
-	  real mfaaa = (distAD.f[dirBSW ])[kbsw];
-	  real mfcaa = (distAD.f[dirBSE ])[kbse];
-	  real mfaca = (distAD.f[dirBNW ])[kbnw];
+	  real mfcbb = (distAD.f[E   ])[ke  ];
+	  real mfabb = (distAD.f[W   ])[kw  ];
+	  real mfbcb = (distAD.f[N   ])[kn  ];
+	  real mfbab = (distAD.f[S   ])[ks  ];
+	  real mfbbc = (distAD.f[T   ])[kt  ];
+	  real mfbba = (distAD.f[B   ])[kb  ];
+	  real mfccb = (distAD.f[NE  ])[kne ];
+	  real mfaab = (distAD.f[SW  ])[ksw ];
+	  real mfcab = (distAD.f[SE  ])[kse ];
+	  real mfacb = (distAD.f[NW  ])[knw ];
+	  real mfcbc = (distAD.f[TE  ])[kte ];
+	  real mfaba = (distAD.f[BW  ])[kbw ];
+	  real mfcba = (distAD.f[BE  ])[kbe ];
+	  real mfabc = (distAD.f[TW  ])[ktw ];
+	  real mfbcc = (distAD.f[TN  ])[ktn ];
+	  real mfbaa = (distAD.f[BS  ])[kbs ];
+	  real mfbca = (distAD.f[BN  ])[kbn ];
+	  real mfbac = (distAD.f[TS  ])[kts ];
+	  real mfbbb = (distAD.f[REST])[k   ];
+	  real mfccc = (distAD.f[TNE ])[ktne];
+	  real mfaac = (distAD.f[TSW ])[ktsw];
+	  real mfcac = (distAD.f[TSE ])[ktse];
+	  real mfacc = (distAD.f[TNW ])[ktnw];
+	  real mfcca = (distAD.f[BNE ])[kbne];
+	  real mfaaa = (distAD.f[BSW ])[kbsw];
+	  real mfcaa = (distAD.f[BSE ])[kbse];
+	  real mfaca = (distAD.f[BNW ])[kbnw];
       //////////////////////////////////////////////////////////////////////////
 	  //! - Calculate concentration using pyramid summation for low round-off errors as in Eq. (J1)-(J3) \ref
 	  //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
@@ -203,8 +204,3 @@ extern "C" __global__ void CalcConc27(
 
    }
 }
-
-
-
-
-
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CalcMac27.cu b/src/gpu/VirtualFluids_GPU/GPU/CalcMac27.cu
index 8b8e66dd633418e21dd4157b0fea933fb0b5be49..a62f4439266dd2ffdb161e703f70517ee82efa40 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CalcMac27.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/CalcMac27.cu
@@ -31,11 +31,12 @@
 //! \author Martin Schoenherr
 //=======================================================================================
 /* Device code */
-#include "LBM/LB.h"
-#include "LBM/D3Q27.h"
-#include <lbm/constants/NumericConstants.h>
+#include "LBM/LB.h" 
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
 
 using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
 
 ////////////////////////////////////////////////////////////////////////////////
 extern "C" __global__ void LBCalcMacCompSP27(
@@ -79,63 +80,63 @@ extern "C" __global__ void LBCalcMacCompSP27(
       Distributions27 dist;
       if (isEvenTimestep)
       {
-         dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+         dist.f[E   ] = &distributions[E   *size_Mat];
+         dist.f[W   ] = &distributions[W   *size_Mat];
+         dist.f[N   ] = &distributions[N   *size_Mat];
+         dist.f[S   ] = &distributions[S   *size_Mat];
+         dist.f[T   ] = &distributions[T   *size_Mat];
+         dist.f[B   ] = &distributions[B   *size_Mat];
+         dist.f[NE  ] = &distributions[NE  *size_Mat];
+         dist.f[SW  ] = &distributions[SW  *size_Mat];
+         dist.f[SE  ] = &distributions[SE  *size_Mat];
+         dist.f[NW  ] = &distributions[NW  *size_Mat];
+         dist.f[TE  ] = &distributions[TE  *size_Mat];
+         dist.f[BW  ] = &distributions[BW  *size_Mat];
+         dist.f[BE  ] = &distributions[BE  *size_Mat];
+         dist.f[TW  ] = &distributions[TW  *size_Mat];
+         dist.f[TN  ] = &distributions[TN  *size_Mat];
+         dist.f[BS  ] = &distributions[BS  *size_Mat];
+         dist.f[BN  ] = &distributions[BN  *size_Mat];
+         dist.f[TS  ] = &distributions[TS  *size_Mat];
+         dist.f[REST] = &distributions[REST*size_Mat];
+         dist.f[TNE ] = &distributions[TNE *size_Mat];
+         dist.f[TSW ] = &distributions[TSW *size_Mat];
+         dist.f[TSE ] = &distributions[TSE *size_Mat];
+         dist.f[TNW ] = &distributions[TNW *size_Mat];
+         dist.f[BNE ] = &distributions[BNE *size_Mat];
+         dist.f[BSW ] = &distributions[BSW *size_Mat];
+         dist.f[BSE ] = &distributions[BSE *size_Mat];
+         dist.f[BNW ] = &distributions[BNW *size_Mat];
       }
       else
       {
-         dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
+         dist.f[W   ] = &distributions[E   *size_Mat];
+         dist.f[E   ] = &distributions[W   *size_Mat];
+         dist.f[S   ] = &distributions[N   *size_Mat];
+         dist.f[N   ] = &distributions[S   *size_Mat];
+         dist.f[B   ] = &distributions[T   *size_Mat];
+         dist.f[T   ] = &distributions[B   *size_Mat];
+         dist.f[SW  ] = &distributions[NE  *size_Mat];
+         dist.f[NE  ] = &distributions[SW  *size_Mat];
+         dist.f[NW  ] = &distributions[SE  *size_Mat];
+         dist.f[SE  ] = &distributions[NW  *size_Mat];
+         dist.f[BW  ] = &distributions[TE  *size_Mat];
+         dist.f[TE  ] = &distributions[BW  *size_Mat];
+         dist.f[TW  ] = &distributions[BE  *size_Mat];
+         dist.f[BE  ] = &distributions[TW  *size_Mat];
+         dist.f[BS  ] = &distributions[TN  *size_Mat];
+         dist.f[TN  ] = &distributions[BS  *size_Mat];
+         dist.f[TS  ] = &distributions[BN  *size_Mat];
+         dist.f[BN  ] = &distributions[TS  *size_Mat];
+         dist.f[REST] = &distributions[REST*size_Mat];
+         dist.f[TNE ] = &distributions[BSW *size_Mat];
+         dist.f[TSW ] = &distributions[BNE *size_Mat];
+         dist.f[TSE ] = &distributions[BNW *size_Mat];
+         dist.f[TNW ] = &distributions[BSE *size_Mat];
+         dist.f[BNE ] = &distributions[TSW *size_Mat];
+         dist.f[BSW ] = &distributions[TNE *size_Mat];
+         dist.f[BSE ] = &distributions[TNW *size_Mat];
+         dist.f[BNW ] = &distributions[TSE *size_Mat];
       }
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set neighbor indices (necessary for indirect addressing)
@@ -169,33 +170,33 @@ extern "C" __global__ void LBCalcMacCompSP27(
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set local distributions
 	  //!
-	  real mfcbb = (dist.f[dirE   ])[k   ];
-	  real mfabb = (dist.f[dirW   ])[kw  ];
-	  real mfbcb = (dist.f[dirN   ])[k   ];
-	  real mfbab = (dist.f[dirS   ])[ks  ];
-	  real mfbbc = (dist.f[dirT   ])[k   ];
-	  real mfbba = (dist.f[dirB   ])[kb  ];
-	  real mfccb = (dist.f[dirNE  ])[k   ];
-	  real mfaab = (dist.f[dirSW  ])[ksw ];
-	  real mfcab = (dist.f[dirSE  ])[ks  ];
-	  real mfacb = (dist.f[dirNW  ])[kw  ];
-	  real mfcbc = (dist.f[dirTE  ])[k   ];
-	  real mfaba = (dist.f[dirBW  ])[kbw ];
-	  real mfcba = (dist.f[dirBE  ])[kb  ];
-	  real mfabc = (dist.f[dirTW  ])[kw  ];
-	  real mfbcc = (dist.f[dirTN  ])[k   ];
-	  real mfbaa = (dist.f[dirBS  ])[kbs ];
-	  real mfbca = (dist.f[dirBN  ])[kb  ];
-	  real mfbac = (dist.f[dirTS  ])[ks  ];
-	  real mfbbb = (dist.f[dirREST])[k   ];
-	  real mfccc = (dist.f[dirTNE ])[k   ];
-	  real mfaac = (dist.f[dirTSW ])[ksw ];
-	  real mfcac = (dist.f[dirTSE ])[ks  ];
-	  real mfacc = (dist.f[dirTNW ])[kw  ];
-	  real mfcca = (dist.f[dirBNE ])[kb  ];
-	  real mfaaa = (dist.f[dirBSW ])[kbsw];
-	  real mfcaa = (dist.f[dirBSE ])[kbs ];
-	  real mfaca = (dist.f[dirBNW ])[kbw ];
+	  real mfcbb = (dist.f[E   ])[k   ];
+	  real mfabb = (dist.f[W   ])[kw  ];
+	  real mfbcb = (dist.f[N   ])[k   ];
+	  real mfbab = (dist.f[S   ])[ks  ];
+	  real mfbbc = (dist.f[T   ])[k   ];
+	  real mfbba = (dist.f[B   ])[kb  ];
+	  real mfccb = (dist.f[NE  ])[k   ];
+	  real mfaab = (dist.f[SW  ])[ksw ];
+	  real mfcab = (dist.f[SE  ])[ks  ];
+	  real mfacb = (dist.f[NW  ])[kw  ];
+	  real mfcbc = (dist.f[TE  ])[k   ];
+	  real mfaba = (dist.f[BW  ])[kbw ];
+	  real mfcba = (dist.f[BE  ])[kb  ];
+	  real mfabc = (dist.f[TW  ])[kw  ];
+	  real mfbcc = (dist.f[TN  ])[k   ];
+	  real mfbaa = (dist.f[BS  ])[kbs ];
+	  real mfbca = (dist.f[BN  ])[kb  ];
+	  real mfbac = (dist.f[TS  ])[ks  ];
+	  real mfbbb = (dist.f[REST])[k   ];
+	  real mfccc = (dist.f[TNE ])[k   ];
+	  real mfaac = (dist.f[TSW ])[ksw ];
+	  real mfcac = (dist.f[TSE ])[ks  ];
+	  real mfacc = (dist.f[TNW ])[kw  ];
+	  real mfcca = (dist.f[BNE ])[kb  ];
+	  real mfaaa = (dist.f[BSW ])[kbsw];
+	  real mfcaa = (dist.f[BSE ])[kbs ];
+	  real mfaca = (dist.f[BNW ])[kbw ];
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set pressure, density and velocity to \f$ 1.0 \f$
 	  //!
@@ -234,21 +235,21 @@ extern "C" __global__ void LBCalcMacCompSP27(
 	  //! - Calculate pressure
 	  //!
 	  real OxxPyyPzz = c1o1;
-      pressure[k] =((dist.f[dirE   ])[ke  ]+ (dist.f[dirW   ])[kw  ]+
-                    (dist.f[dirN   ])[kn  ]+ (dist.f[dirS   ])[ks  ]+
-                    (dist.f[dirT   ])[kt  ]+ (dist.f[dirB   ])[kb  ]+
+      pressure[k] =((dist.f[E   ])[ke  ]+ (dist.f[W   ])[kw  ]+
+                    (dist.f[N   ])[kn  ]+ (dist.f[S   ])[ks  ]+
+                    (dist.f[T   ])[kt  ]+ (dist.f[B   ])[kb  ]+
                     c2o1*(
-                    (dist.f[dirNE  ])[kne ]+ (dist.f[dirSW  ])[ksw ]+
-                    (dist.f[dirSE  ])[kse ]+ (dist.f[dirNW  ])[knw ]+
-                    (dist.f[dirTE  ])[kte ]+ (dist.f[dirBW  ])[kbw ]+
-                    (dist.f[dirBE  ])[kbe ]+ (dist.f[dirTW  ])[ktw ]+
-                    (dist.f[dirTN  ])[ktn ]+ (dist.f[dirBS  ])[kbs ]+
-                    (dist.f[dirBN  ])[kbn ]+ (dist.f[dirTS  ])[kts ])+
+                    (dist.f[NE  ])[kne ]+ (dist.f[SW  ])[ksw ]+
+                    (dist.f[SE  ])[kse ]+ (dist.f[NW  ])[knw ]+
+                    (dist.f[TE  ])[kte ]+ (dist.f[BW  ])[kbw ]+
+                    (dist.f[BE  ])[kbe ]+ (dist.f[TW  ])[ktw ]+
+                    (dist.f[TN  ])[ktn ]+ (dist.f[BS  ])[kbs ]+
+                    (dist.f[BN  ])[kbn ]+ (dist.f[TS  ])[kts ])+
                     c3o1*(
-                    (dist.f[dirTNE ])[ktne]+ (dist.f[dirTSW ])[ktsw]+
-                    (dist.f[dirTSE ])[ktse]+ (dist.f[dirTNW ])[ktnw]+
-                    (dist.f[dirBNE ])[kbne]+ (dist.f[dirBSW ])[kbsw]+
-                    (dist.f[dirBSE ])[kbse]+ (dist.f[dirBNW ])[kbnw])-
+                    (dist.f[TNE ])[ktne]+ (dist.f[TSW ])[ktsw]+
+                    (dist.f[TSE ])[ktse]+ (dist.f[TNW ])[ktnw]+
+                    (dist.f[BNE ])[kbne]+ (dist.f[BSW ])[kbsw]+
+                    (dist.f[BSE ])[kbse]+ (dist.f[BNW ])[kbnw])-
                     rho[k]-(velocityX[k] * velocityX[k] + velocityY[k] * velocityY[k] + velocityZ[k] * velocityZ[k]) * (c1o1+rho[k])) * (c1o1 / OxxPyyPzz - c1o2) +rho[k];
    }
 }
@@ -314,125 +315,125 @@ extern "C" __global__ void LBCalcMacADCompSP27(
       Distributions27 dist;
       if (isEvenTimestep)
       {
-         dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+         dist.f[E   ] = &distributions[E   *size_Mat];
+         dist.f[W   ] = &distributions[W   *size_Mat];
+         dist.f[N   ] = &distributions[N   *size_Mat];
+         dist.f[S   ] = &distributions[S   *size_Mat];
+         dist.f[T   ] = &distributions[T   *size_Mat];
+         dist.f[B   ] = &distributions[B   *size_Mat];
+         dist.f[NE  ] = &distributions[NE  *size_Mat];
+         dist.f[SW  ] = &distributions[SW  *size_Mat];
+         dist.f[SE  ] = &distributions[SE  *size_Mat];
+         dist.f[NW  ] = &distributions[NW  *size_Mat];
+         dist.f[TE  ] = &distributions[TE  *size_Mat];
+         dist.f[BW  ] = &distributions[BW  *size_Mat];
+         dist.f[BE  ] = &distributions[BE  *size_Mat];
+         dist.f[TW  ] = &distributions[TW  *size_Mat];
+         dist.f[TN  ] = &distributions[TN  *size_Mat];
+         dist.f[BS  ] = &distributions[BS  *size_Mat];
+         dist.f[BN  ] = &distributions[BN  *size_Mat];
+         dist.f[TS  ] = &distributions[TS  *size_Mat];
+         dist.f[REST] = &distributions[REST*size_Mat];
+         dist.f[TNE ] = &distributions[TNE *size_Mat];
+         dist.f[TSW ] = &distributions[TSW *size_Mat];
+         dist.f[TSE ] = &distributions[TSE *size_Mat];
+         dist.f[TNW ] = &distributions[TNW *size_Mat];
+         dist.f[BNE ] = &distributions[BNE *size_Mat];
+         dist.f[BSW ] = &distributions[BSW *size_Mat];
+         dist.f[BSE ] = &distributions[BSE *size_Mat];
+         dist.f[BNW ] = &distributions[BNW *size_Mat];
       }
       else
       {
-         dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
+         dist.f[W   ] = &distributions[E   *size_Mat];
+         dist.f[E   ] = &distributions[W   *size_Mat];
+         dist.f[S   ] = &distributions[N   *size_Mat];
+         dist.f[N   ] = &distributions[S   *size_Mat];
+         dist.f[B   ] = &distributions[T   *size_Mat];
+         dist.f[T   ] = &distributions[B   *size_Mat];
+         dist.f[SW  ] = &distributions[NE  *size_Mat];
+         dist.f[NE  ] = &distributions[SW  *size_Mat];
+         dist.f[NW  ] = &distributions[SE  *size_Mat];
+         dist.f[SE  ] = &distributions[NW  *size_Mat];
+         dist.f[BW  ] = &distributions[TE  *size_Mat];
+         dist.f[TE  ] = &distributions[BW  *size_Mat];
+         dist.f[TW  ] = &distributions[BE  *size_Mat];
+         dist.f[BE  ] = &distributions[TW  *size_Mat];
+         dist.f[BS  ] = &distributions[TN  *size_Mat];
+         dist.f[TN  ] = &distributions[BS  *size_Mat];
+         dist.f[TS  ] = &distributions[BN  *size_Mat];
+         dist.f[BN  ] = &distributions[TS  *size_Mat];
+         dist.f[REST] = &distributions[REST*size_Mat];
+         dist.f[TNE ] = &distributions[BSW *size_Mat];
+         dist.f[TSW ] = &distributions[BNE *size_Mat];
+         dist.f[TSE ] = &distributions[BNW *size_Mat];
+         dist.f[TNW ] = &distributions[BSE *size_Mat];
+         dist.f[BNE ] = &distributions[TSW *size_Mat];
+         dist.f[BSW ] = &distributions[TNE *size_Mat];
+         dist.f[BSE ] = &distributions[TNW *size_Mat];
+         dist.f[BNW ] = &distributions[TSE *size_Mat];
       }
       ////////////////////////////////////////////////////////////////////////////////
        Distributions27 distAD;
        if (isEvenTimestep)
        {
-           distAD.f[dirE   ] = &distributionsAD[dirE   *size_Mat];
-           distAD.f[dirW   ] = &distributionsAD[dirW   *size_Mat];
-           distAD.f[dirN   ] = &distributionsAD[dirN   *size_Mat];
-           distAD.f[dirS   ] = &distributionsAD[dirS   *size_Mat];
-           distAD.f[dirT   ] = &distributionsAD[dirT   *size_Mat];
-           distAD.f[dirB   ] = &distributionsAD[dirB   *size_Mat];
-           distAD.f[dirNE  ] = &distributionsAD[dirNE  *size_Mat];
-           distAD.f[dirSW  ] = &distributionsAD[dirSW  *size_Mat];
-           distAD.f[dirSE  ] = &distributionsAD[dirSE  *size_Mat];
-           distAD.f[dirNW  ] = &distributionsAD[dirNW  *size_Mat];
-           distAD.f[dirTE  ] = &distributionsAD[dirTE  *size_Mat];
-           distAD.f[dirBW  ] = &distributionsAD[dirBW  *size_Mat];
-           distAD.f[dirBE  ] = &distributionsAD[dirBE  *size_Mat];
-           distAD.f[dirTW  ] = &distributionsAD[dirTW  *size_Mat];
-           distAD.f[dirTN  ] = &distributionsAD[dirTN  *size_Mat];
-           distAD.f[dirBS  ] = &distributionsAD[dirBS  *size_Mat];
-           distAD.f[dirBN  ] = &distributionsAD[dirBN  *size_Mat];
-           distAD.f[dirTS  ] = &distributionsAD[dirTS  *size_Mat];
-           distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-           distAD.f[dirTNE ] = &distributionsAD[dirTNE *size_Mat];
-           distAD.f[dirTSW ] = &distributionsAD[dirTSW *size_Mat];
-           distAD.f[dirTSE ] = &distributionsAD[dirTSE *size_Mat];
-           distAD.f[dirTNW ] = &distributionsAD[dirTNW *size_Mat];
-           distAD.f[dirBNE ] = &distributionsAD[dirBNE *size_Mat];
-           distAD.f[dirBSW ] = &distributionsAD[dirBSW *size_Mat];
-           distAD.f[dirBSE ] = &distributionsAD[dirBSE *size_Mat];
-           distAD.f[dirBNW ] = &distributionsAD[dirBNW *size_Mat];
+           distAD.f[E   ] = &distributionsAD[E   *size_Mat];
+           distAD.f[W   ] = &distributionsAD[W   *size_Mat];
+           distAD.f[N   ] = &distributionsAD[N   *size_Mat];
+           distAD.f[S   ] = &distributionsAD[S   *size_Mat];
+           distAD.f[T   ] = &distributionsAD[T   *size_Mat];
+           distAD.f[B   ] = &distributionsAD[B   *size_Mat];
+           distAD.f[NE  ] = &distributionsAD[NE  *size_Mat];
+           distAD.f[SW  ] = &distributionsAD[SW  *size_Mat];
+           distAD.f[SE  ] = &distributionsAD[SE  *size_Mat];
+           distAD.f[NW  ] = &distributionsAD[NW  *size_Mat];
+           distAD.f[TE  ] = &distributionsAD[TE  *size_Mat];
+           distAD.f[BW  ] = &distributionsAD[BW  *size_Mat];
+           distAD.f[BE  ] = &distributionsAD[BE  *size_Mat];
+           distAD.f[TW  ] = &distributionsAD[TW  *size_Mat];
+           distAD.f[TN  ] = &distributionsAD[TN  *size_Mat];
+           distAD.f[BS  ] = &distributionsAD[BS  *size_Mat];
+           distAD.f[BN  ] = &distributionsAD[BN  *size_Mat];
+           distAD.f[TS  ] = &distributionsAD[TS  *size_Mat];
+           distAD.f[REST] = &distributionsAD[REST*size_Mat];
+           distAD.f[TNE ] = &distributionsAD[TNE *size_Mat];
+           distAD.f[TSW ] = &distributionsAD[TSW *size_Mat];
+           distAD.f[TSE ] = &distributionsAD[TSE *size_Mat];
+           distAD.f[TNW ] = &distributionsAD[TNW *size_Mat];
+           distAD.f[BNE ] = &distributionsAD[BNE *size_Mat];
+           distAD.f[BSW ] = &distributionsAD[BSW *size_Mat];
+           distAD.f[BSE ] = &distributionsAD[BSE *size_Mat];
+           distAD.f[BNW ] = &distributionsAD[BNW *size_Mat];
        }
        else
        {
-           distAD.f[dirW   ] = &distributionsAD[dirE   *size_Mat];
-           distAD.f[dirE   ] = &distributionsAD[dirW   *size_Mat];
-           distAD.f[dirS   ] = &distributionsAD[dirN   *size_Mat];
-           distAD.f[dirN   ] = &distributionsAD[dirS   *size_Mat];
-           distAD.f[dirB   ] = &distributionsAD[dirT   *size_Mat];
-           distAD.f[dirT   ] = &distributionsAD[dirB   *size_Mat];
-           distAD.f[dirSW  ] = &distributionsAD[dirNE  *size_Mat];
-           distAD.f[dirNE  ] = &distributionsAD[dirSW  *size_Mat];
-           distAD.f[dirNW  ] = &distributionsAD[dirSE  *size_Mat];
-           distAD.f[dirSE  ] = &distributionsAD[dirNW  *size_Mat];
-           distAD.f[dirBW  ] = &distributionsAD[dirTE  *size_Mat];
-           distAD.f[dirTE  ] = &distributionsAD[dirBW  *size_Mat];
-           distAD.f[dirTW  ] = &distributionsAD[dirBE  *size_Mat];
-           distAD.f[dirBE  ] = &distributionsAD[dirTW  *size_Mat];
-           distAD.f[dirBS  ] = &distributionsAD[dirTN  *size_Mat];
-           distAD.f[dirTN  ] = &distributionsAD[dirBS  *size_Mat];
-           distAD.f[dirTS  ] = &distributionsAD[dirBN  *size_Mat];
-           distAD.f[dirBN  ] = &distributionsAD[dirTS  *size_Mat];
-           distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-           distAD.f[dirBSW ] = &distributionsAD[dirTNE *size_Mat];
-           distAD.f[dirBNE ] = &distributionsAD[dirTSW *size_Mat];
-           distAD.f[dirBNW ] = &distributionsAD[dirTSE *size_Mat];
-           distAD.f[dirBSE ] = &distributionsAD[dirTNW *size_Mat];
-           distAD.f[dirTSW ] = &distributionsAD[dirBNE *size_Mat];
-           distAD.f[dirTNE ] = &distributionsAD[dirBSW *size_Mat];
-           distAD.f[dirTNW ] = &distributionsAD[dirBSE *size_Mat];
-           distAD.f[dirTSE ] = &distributionsAD[dirBNW *size_Mat];
+           distAD.f[W   ] = &distributionsAD[E   *size_Mat];
+           distAD.f[E   ] = &distributionsAD[W   *size_Mat];
+           distAD.f[S   ] = &distributionsAD[N   *size_Mat];
+           distAD.f[N   ] = &distributionsAD[S   *size_Mat];
+           distAD.f[B   ] = &distributionsAD[T   *size_Mat];
+           distAD.f[T   ] = &distributionsAD[B   *size_Mat];
+           distAD.f[SW  ] = &distributionsAD[NE  *size_Mat];
+           distAD.f[NE  ] = &distributionsAD[SW  *size_Mat];
+           distAD.f[NW  ] = &distributionsAD[SE  *size_Mat];
+           distAD.f[SE  ] = &distributionsAD[NW  *size_Mat];
+           distAD.f[BW  ] = &distributionsAD[TE  *size_Mat];
+           distAD.f[TE  ] = &distributionsAD[BW  *size_Mat];
+           distAD.f[TW  ] = &distributionsAD[BE  *size_Mat];
+           distAD.f[BE  ] = &distributionsAD[TW  *size_Mat];
+           distAD.f[BS  ] = &distributionsAD[TN  *size_Mat];
+           distAD.f[TN  ] = &distributionsAD[BS  *size_Mat];
+           distAD.f[TS  ] = &distributionsAD[BN  *size_Mat];
+           distAD.f[BN  ] = &distributionsAD[TS  *size_Mat];
+           distAD.f[REST] = &distributionsAD[REST*size_Mat];
+           distAD.f[BSW ] = &distributionsAD[TNE *size_Mat];
+           distAD.f[BNE ] = &distributionsAD[TSW *size_Mat];
+           distAD.f[BNW ] = &distributionsAD[TSE *size_Mat];
+           distAD.f[BSE ] = &distributionsAD[TNW *size_Mat];
+           distAD.f[TSW ] = &distributionsAD[BNE *size_Mat];
+           distAD.f[TNE ] = &distributionsAD[BSW *size_Mat];
+           distAD.f[TNW ] = &distributionsAD[BSE *size_Mat];
+           distAD.f[TSE ] = &distributionsAD[BNW *size_Mat];
        }
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set neighbor indices (necessary for indirect addressing)
@@ -466,63 +467,63 @@ extern "C" __global__ void LBCalcMacADCompSP27(
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set local distributions
 	  //!
-	  real mfcbb = (dist.f[dirE   ])[k   ];
-	  real mfabb = (dist.f[dirW   ])[kw  ];
-	  real mfbcb = (dist.f[dirN   ])[k   ];
-	  real mfbab = (dist.f[dirS   ])[ks  ];
-	  real mfbbc = (dist.f[dirT   ])[k   ];
-	  real mfbba = (dist.f[dirB   ])[kb  ];
-	  real mfccb = (dist.f[dirNE  ])[k   ];
-	  real mfaab = (dist.f[dirSW  ])[ksw ];
-	  real mfcab = (dist.f[dirSE  ])[ks  ];
-	  real mfacb = (dist.f[dirNW  ])[kw  ];
-	  real mfcbc = (dist.f[dirTE  ])[k   ];
-	  real mfaba = (dist.f[dirBW  ])[kbw ];
-	  real mfcba = (dist.f[dirBE  ])[kb  ];
-	  real mfabc = (dist.f[dirTW  ])[kw  ];
-	  real mfbcc = (dist.f[dirTN  ])[k   ];
-	  real mfbaa = (dist.f[dirBS  ])[kbs ];
-	  real mfbca = (dist.f[dirBN  ])[kb  ];
-	  real mfbac = (dist.f[dirTS  ])[ks  ];
-	  real mfbbb = (dist.f[dirREST])[k   ];
-	  real mfccc = (dist.f[dirTNE ])[k   ];
-	  real mfaac = (dist.f[dirTSW ])[ksw ];
-	  real mfcac = (dist.f[dirTSE ])[ks  ];
-	  real mfacc = (dist.f[dirTNW ])[kw  ];
-	  real mfcca = (dist.f[dirBNE ])[kb  ];
-	  real mfaaa = (dist.f[dirBSW ])[kbsw];
-	  real mfcaa = (dist.f[dirBSE ])[kbs ];
-	  real mfaca = (dist.f[dirBNW ])[kbw ];
+	  real mfcbb = (dist.f[E   ])[k   ];
+	  real mfabb = (dist.f[W   ])[kw  ];
+	  real mfbcb = (dist.f[N   ])[k   ];
+	  real mfbab = (dist.f[S   ])[ks  ];
+	  real mfbbc = (dist.f[T   ])[k   ];
+	  real mfbba = (dist.f[B   ])[kb  ];
+	  real mfccb = (dist.f[NE  ])[k   ];
+	  real mfaab = (dist.f[SW  ])[ksw ];
+	  real mfcab = (dist.f[SE  ])[ks  ];
+	  real mfacb = (dist.f[NW  ])[kw  ];
+	  real mfcbc = (dist.f[TE  ])[k   ];
+	  real mfaba = (dist.f[BW  ])[kbw ];
+	  real mfcba = (dist.f[BE  ])[kb  ];
+	  real mfabc = (dist.f[TW  ])[kw  ];
+	  real mfbcc = (dist.f[TN  ])[k   ];
+	  real mfbaa = (dist.f[BS  ])[kbs ];
+	  real mfbca = (dist.f[BN  ])[kb  ];
+	  real mfbac = (dist.f[TS  ])[ks  ];
+	  real mfbbb = (dist.f[REST])[k   ];
+	  real mfccc = (dist.f[TNE ])[k   ];
+	  real mfaac = (dist.f[TSW ])[ksw ];
+	  real mfcac = (dist.f[TSE ])[ks  ];
+	  real mfacc = (dist.f[TNW ])[kw  ];
+	  real mfcca = (dist.f[BNE ])[kb  ];
+	  real mfaaa = (dist.f[BSW ])[kbsw];
+	  real mfcaa = (dist.f[BSE ])[kbs ];
+	  real mfaca = (dist.f[BNW ])[kbw ];
 	  ////////////////////////////////////////////////////////////////////////////////////
        //! - Set local distributions Advection Diffusion
        //!
-       real fcbb = (distAD.f[dirE   ])[k];
-       real fabb = (distAD.f[dirW   ])[kw];
-       real fbcb = (distAD.f[dirN   ])[k];
-       real fbab = (distAD.f[dirS   ])[ks];
-       real fbbc = (distAD.f[dirT   ])[k];
-       real fbba = (distAD.f[dirB   ])[kb];
-       real fccb = (distAD.f[dirNE  ])[k];
-       real faab = (distAD.f[dirSW  ])[ksw];
-       real fcab = (distAD.f[dirSE  ])[ks];
-       real facb = (distAD.f[dirNW  ])[kw];
-       real fcbc = (distAD.f[dirTE  ])[k];
-       real faba = (distAD.f[dirBW  ])[kbw];
-       real fcba = (distAD.f[dirBE  ])[kb];
-       real fabc = (distAD.f[dirTW  ])[kw];
-       real fbcc = (distAD.f[dirTN  ])[k];
-       real fbaa = (distAD.f[dirBS  ])[kbs];
-       real fbca = (distAD.f[dirBN  ])[kb];
-       real fbac = (distAD.f[dirTS  ])[ks];
-       real fbbb = (distAD.f[dirREST])[k];
-       real fccc = (distAD.f[dirTNE ])[k];
-       real faac = (distAD.f[dirTSW ])[ksw];
-       real fcac = (distAD.f[dirTSE ])[ks];
-       real facc = (distAD.f[dirTNW ])[kw];
-       real fcca = (distAD.f[dirBNE ])[kb];
-       real faaa = (distAD.f[dirBSW ])[kbsw];
-       real fcaa = (distAD.f[dirBSE ])[kbs];
-       real faca = (distAD.f[dirBNW ])[kbw];
+       real fcbb = (distAD.f[E   ])[k];
+       real fabb = (distAD.f[W   ])[kw];
+       real fbcb = (distAD.f[N   ])[k];
+       real fbab = (distAD.f[S   ])[ks];
+       real fbbc = (distAD.f[T   ])[k];
+       real fbba = (distAD.f[B   ])[kb];
+       real fccb = (distAD.f[NE  ])[k];
+       real faab = (distAD.f[SW  ])[ksw];
+       real fcab = (distAD.f[SE  ])[ks];
+       real facb = (distAD.f[NW  ])[kw];
+       real fcbc = (distAD.f[TE  ])[k];
+       real faba = (distAD.f[BW  ])[kbw];
+       real fcba = (distAD.f[BE  ])[kb];
+       real fabc = (distAD.f[TW  ])[kw];
+       real fbcc = (distAD.f[TN  ])[k];
+       real fbaa = (distAD.f[BS  ])[kbs];
+       real fbca = (distAD.f[BN  ])[kb];
+       real fbac = (distAD.f[TS  ])[ks];
+       real fbbb = (distAD.f[REST])[k];
+       real fccc = (distAD.f[TNE ])[k];
+       real faac = (distAD.f[TSW ])[ksw];
+       real fcac = (distAD.f[TSE ])[ks];
+       real facc = (distAD.f[TNW ])[kw];
+       real fcca = (distAD.f[BNE ])[kb];
+       real faaa = (distAD.f[BSW ])[kbsw];
+       real fcaa = (distAD.f[BSE ])[kbs];
+       real faca = (distAD.f[BNW ])[kbw];
 	  ////////////////////////////////////////////////////////////////////////////////
 	  //! - Set pressure, density and velocity to \f$ 1.0 \f$
 	  //!
@@ -574,21 +575,21 @@ extern "C" __global__ void LBCalcMacADCompSP27(
 	  //! - Calculate pressure
 	  //!
 	  real OxxPyyPzz = c1o1;
-      pressure[k] =((dist.f[dirE   ])[ke  ]+ (dist.f[dirW   ])[kw  ]+
-                    (dist.f[dirN   ])[kn  ]+ (dist.f[dirS   ])[ks  ]+
-                    (dist.f[dirT   ])[kt  ]+ (dist.f[dirB   ])[kb  ]+
+      pressure[k] =((dist.f[E   ])[ke  ]+ (dist.f[W   ])[kw  ]+
+                    (dist.f[N   ])[kn  ]+ (dist.f[S   ])[ks  ]+
+                    (dist.f[T   ])[kt  ]+ (dist.f[B   ])[kb  ]+
                     c2o1*(
-                    (dist.f[dirNE  ])[kne ]+ (dist.f[dirSW  ])[ksw ]+
-                    (dist.f[dirSE  ])[kse ]+ (dist.f[dirNW  ])[knw ]+
-                    (dist.f[dirTE  ])[kte ]+ (dist.f[dirBW  ])[kbw ]+
-                    (dist.f[dirBE  ])[kbe ]+ (dist.f[dirTW  ])[ktw ]+
-                    (dist.f[dirTN  ])[ktn ]+ (dist.f[dirBS  ])[kbs ]+
-                    (dist.f[dirBN  ])[kbn ]+ (dist.f[dirTS  ])[kts ])+
+                    (dist.f[NE  ])[kne ]+ (dist.f[SW  ])[ksw ]+
+                    (dist.f[SE  ])[kse ]+ (dist.f[NW  ])[knw ]+
+                    (dist.f[TE  ])[kte ]+ (dist.f[BW  ])[kbw ]+
+                    (dist.f[BE  ])[kbe ]+ (dist.f[TW  ])[ktw ]+
+                    (dist.f[TN  ])[ktn ]+ (dist.f[BS  ])[kbs ]+
+                    (dist.f[BN  ])[kbn ]+ (dist.f[TS  ])[kts ])+
                     c3o1*(
-                    (dist.f[dirTNE ])[ktne]+ (dist.f[dirTSW ])[ktsw]+
-                    (dist.f[dirTSE ])[ktse]+ (dist.f[dirTNW ])[ktnw]+
-                    (dist.f[dirBNE ])[kbne]+ (dist.f[dirBSW ])[kbsw]+
-                    (dist.f[dirBSE ])[kbse]+ (dist.f[dirBNW ])[kbnw])-
+                    (dist.f[TNE ])[ktne]+ (dist.f[TSW ])[ktsw]+
+                    (dist.f[TSE ])[ktse]+ (dist.f[TNW ])[ktnw]+
+                    (dist.f[BNE ])[kbne]+ (dist.f[BSW ])[kbsw]+
+                    (dist.f[BSE ])[kbse]+ (dist.f[BNW ])[kbnw])-
                     rho[k]-(velocityX[k] * velocityX[k] + velocityY[k] * velocityY[k] + velocityZ[k] * velocityZ[k]) * (c1o1+rho[k])) * (c1o1 / OxxPyyPzz - c1o2) +rho[k];
    }
 }
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.cpp b/src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.cpp
deleted file mode 100644
index 3202144810c83e913c2bf5881b967bf78b4675e2..0000000000000000000000000000000000000000
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-//=======================================================================================
-// ____          ____    __    ______     __________   __      __       __        __
-// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
-//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
-//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
-//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
-//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
-//      \    \  |    |   ________________________________________________________________
-//       \    \ |    |  |  ______________________________________________________________|
-//        \    \|    |  |  |         __          __     __     __     ______      _______
-//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
-//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
-//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
-//
-//  This file is part of VirtualFluids. VirtualFluids is free software: you can
-//  redistribute it and/or modify it under the terms of the GNU General Public
-//  License as published by the Free Software Foundation, either version 3 of
-//  the License, or (at your option) any later version.
-//
-//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
-//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-//  for more details.
-//
-//  You should have received a copy of the GNU General Public License along
-//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file CudaKernelManager.cpp
-//! \ingroup GPU
-//! \author Martin Schoenherr
-//=======================================================================================
-#include <cuda_runtime.h>
-#include <helper_cuda.h>
-#include "CudaKernelManager.h"
-#include "GPU_Interface.h"
-#include <Parameter/Parameter.h>
-
-
-void CudaKernelManager::runLBMKernel(SPtr<Parameter> para)
-{
-    if (para->getIsADcalculationOn()) {
-		CumulantK17LBMDeviceKernelAD(
-			para->getParD()->numberofthreads,
-			para->getParD()->omega,
-			para->getParD()->typeOfGridNode,
-			para->getParD()->neighborX,
-			para->getParD()->neighborY,
-			para->getParD()->neighborZ,
-			para->getParD()->distributions.f[0],
-			para->getParD()->distributionsAD.f[0],
-			para->getParD()->numberOfNodes,
-			para->getParD()->forcing,
-			para->getParD()->isEvenTimestep);
-    } else {
-		CumulantK17LBMDeviceKernel(
-			para->getParD()->numberofthreads,
-			para->getParD()->omega,
-			para->getParD()->typeOfGridNode,
-			para->getParD()->neighborX,
-			para->getParD()->neighborY,
-			para->getParD()->neighborZ,
-			para->getParD()->distributions.f[0],
-			para->getParD()->numberOfNodes,
-			para->getParD()->forcing,
-			para->getParD()->isEvenTimestep);
-	}
-}
-
-void CudaKernelManager::runVelocityBCKernel(SPtr<Parameter> para)
-{
-	if (para->getParD()->numberOfVeloBCnodes > 0)
-	{
-		QVelDevicePlainBB27(
-			para->getParD()->numberofthreads,
-			para->getParD()->veloBC.Vx,
-			para->getParD()->veloBC.Vy,
-			para->getParD()->veloBC.Vz,
-			para->getParD()->distributions.f[0],
-			para->getParD()->veloBC.k,
-			para->getParD()->veloBC.q27[0],
-			para->getParD()->numberOfVeloBCnodes,
-			para->getParD()->veloBC.kArray,
-			para->getParD()->neighborX,
-			para->getParD()->neighborY,
-			para->getParD()->neighborZ,
-			para->getParD()->numberOfNodes,
-			para->getParD()->isEvenTimestep);
-	}
-}
-
-void CudaKernelManager::runGeoBCKernel(SPtr<Parameter> para)
-{
-    if (para->getParD()->numberOfVeloBCnodes > 0)
-    {
-        // ...
-    }
-}
-
-void CudaKernelManager::calculateMacroscopicValues(SPtr<Parameter> para)
-{
-    if (para->getIsADcalculationOn()) {
-		CalcMacADCompSP27(
-			para->getParD()->velocityX,
-			para->getParD()->velocityY,
-			para->getParD()->velocityZ,
-			para->getParD()->rho,
-			para->getParD()->pressure,
-			para->getParD()->typeOfGridNode,
-			para->getParD()->neighborX,
-			para->getParD()->neighborY,
-			para->getParD()->neighborZ,
-			para->getParD()->numberOfNodes,
-			para->getParD()->numberofthreads,
-			para->getParD()->distributions.f[0],
-			para->getParD()->distributionsAD.f[0],
-            para->getParD()->forcing,
-			para->getParD()->isEvenTimestep);
-    } else {
-		CalcMacCompSP27(
-			para->getParD()->velocityX,
-			para->getParD()->velocityY,
-			para->getParD()->velocityZ,
-			para->getParD()->rho,
-			para->getParD()->pressure,
-			para->getParD()->typeOfGridNode,
-			para->getParD()->neighborX,
-			para->getParD()->neighborY,
-			para->getParD()->neighborZ,
-			para->getParD()->numberOfNodes,
-			para->getParD()->numberofthreads,
-			para->getParD()->distributions.f[0],
-			para->getParD()->isEvenTimestep);
-	}
-}
-
-
-
-
-
-
-
-
-
-
-
-SPtr<CudaKernelManager> CudaKernelManager::make(SPtr<Parameter> parameter)
-{
-    return SPtr<CudaKernelManager>(new CudaKernelManager(parameter));
-}
-
-CudaKernelManager::CudaKernelManager(SPtr<Parameter> parameter)
-{
-    this->parameter = parameter;
-}
-
-CudaKernelManager::CudaKernelManager(const CudaKernelManager&)
-{
-
-}
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
index 364843deb94fd6730940055f5cba10179f057265..652cf53b6faf0e26b0da0c33a773be92ca0f7ad9 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
+++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
@@ -143,22 +143,22 @@ void CudaMemoryManager::cudaFreeSP()
 //slip boundary condition
 void CudaMemoryManager::cudaAllocSlipBC()
 {
-	unsigned int mem_size_slip_BC_INT  = sizeof(int)  * parameter->getParH()->numberOfSlipBCnodes;
-	unsigned int mem_size_slip_BC_REAL = sizeof(real) * parameter->getParH()->numberOfSlipBCnodes;
+	unsigned int mem_size_slip_BC_INT  = sizeof(int)  * parameter->getParH()->slipBC.numberOfBCnodes;
+	unsigned int mem_size_slip_BC_REAL = sizeof(real) * parameter->getParH()->slipBC.numberOfBCnodes;
 
 	//Host
 	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.q27[0]), parameter->getD3Qxx() * mem_size_slip_BC_REAL));
 	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.k),                              mem_size_slip_BC_INT));
-	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.NormalX),                        mem_size_slip_BC_REAL));
-	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.NormalY),                        mem_size_slip_BC_REAL));
-	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.NormalZ),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.normalX),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.normalY),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMallocHost((void**)&(parameter->getParH()->slipBC.normalZ),                        mem_size_slip_BC_REAL));
 
 	//Device
 	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.q27[0]), parameter->getD3Qxx() * mem_size_slip_BC_REAL));
 	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.k),                              mem_size_slip_BC_INT));
-	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.NormalX),                        mem_size_slip_BC_REAL));
-	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.NormalY),                        mem_size_slip_BC_REAL));
-	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.NormalZ),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.normalX),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.normalY),                        mem_size_slip_BC_REAL));
+	checkCudaErrors(cudaMalloc((void**)&(parameter->getParD()->slipBC.normalZ),                        mem_size_slip_BC_REAL));
 
 	//////////////////////////////////////////////////////////////////////////
 	double tmp = (double)mem_size_slip_BC_INT + 4. * (double)mem_size_slip_BC_REAL + (double)parameter->getD3Qxx() * (double)mem_size_slip_BC_REAL;
@@ -166,23 +166,23 @@ void CudaMemoryManager::cudaAllocSlipBC()
 }
 void CudaMemoryManager::cudaCopySlipBC()
 {
-	unsigned int mem_size_slip_BC_INT  = sizeof(int)  * parameter->getParH()->numberOfSlipBCnodes;
-	unsigned int mem_size_slip_BC_REAL = sizeof(real) * parameter->getParH()->numberOfSlipBCnodes;
+	unsigned int mem_size_slip_BC_INT  = sizeof(int)  * parameter->getParH()->slipBC.numberOfBCnodes;
+	unsigned int mem_size_slip_BC_REAL = sizeof(real) * parameter->getParH()->slipBC.numberOfBCnodes;
 
 	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.q27[0],  parameter->getParH()->slipBC.q27[0], parameter->getD3Qxx() * mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
 	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.k,       parameter->getParH()->slipBC.k,							  mem_size_slip_BC_INT,  cudaMemcpyHostToDevice));
-	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.NormalX, parameter->getParH()->slipBC.NormalX,                        mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
-	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.NormalY, parameter->getParH()->slipBC.NormalY,                        mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
-	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.NormalZ, parameter->getParH()->slipBC.NormalZ,						  mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
+	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.normalX, parameter->getParH()->slipBC.normalX,                        mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
+	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.normalY, parameter->getParH()->slipBC.normalY,                        mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
+	checkCudaErrors(cudaMemcpy(parameter->getParD()->slipBC.normalZ, parameter->getParH()->slipBC.normalZ,						  mem_size_slip_BC_REAL, cudaMemcpyHostToDevice));
 
 }
 void CudaMemoryManager::cudaFreeSlipBC()
 {
 	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.q27[0]));
 	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.k));
-	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.NormalX));
-	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.NormalY));
-	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.NormalZ));
+	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.normalX));
+	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.normalY));
+	checkCudaErrors(cudaFreeHost(parameter->getParH()->slipBC.normalZ));
 }
 
 
@@ -192,22 +192,22 @@ void CudaMemoryManager::cudaFreeSlipBC()
 //velocity boundary condition
 void CudaMemoryManager::cudaAllocVeloBC()
 {
-	unsigned int mem_size_inflow_BC_INT = sizeof(int)*parameter->getParH()->numberOfVeloBCnodes;
-	unsigned int mem_size_inflow_BC_REAL = sizeof(real)*parameter->getParH()->numberOfVeloBCnodes;
+	unsigned int mem_size_inflow_BC_INT = sizeof(int)*parameter->getParH()->velocityBC.numberOfBCnodes;
+	unsigned int mem_size_inflow_BC_REAL = sizeof(real)*parameter->getParH()->velocityBC.numberOfBCnodes;
 
 	//Host
-	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->veloBC.q27[0]), parameter->getD3Qxx() * mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->veloBC.k),								 mem_size_inflow_BC_INT  ));
-	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->veloBC.Vx),				             mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->veloBC.Vy),				             mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->veloBC.Vz),				             mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->velocityBC.q27[0]), parameter->getD3Qxx() * mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->velocityBC.k),								 mem_size_inflow_BC_INT  ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->velocityBC.Vx),				             mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->velocityBC.Vy),				             mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->velocityBC.Vz),				             mem_size_inflow_BC_REAL ));
 
 	//Device
-	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->veloBC.q27[0]),     parameter->getD3Qxx() * mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->veloBC.k),									 mem_size_inflow_BC_INT  ));
-	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->veloBC.Vx),				                 mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->veloBC.Vy),				                 mem_size_inflow_BC_REAL ));
-	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->veloBC.Vz),				                 mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->velocityBC.q27[0]),     parameter->getD3Qxx() * mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->velocityBC.k),									 mem_size_inflow_BC_INT  ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->velocityBC.Vx),				                 mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->velocityBC.Vy),				                 mem_size_inflow_BC_REAL ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->velocityBC.Vz),				                 mem_size_inflow_BC_REAL ));
 
 	//////////////////////////////////////////////////////////////////////////
 	double tmp = (double)mem_size_inflow_BC_INT + 4. * (double)mem_size_inflow_BC_REAL + (double)parameter->getD3Qxx() * (double)mem_size_inflow_BC_REAL;
@@ -215,26 +215,126 @@ void CudaMemoryManager::cudaAllocVeloBC()
 }
 void CudaMemoryManager::cudaCopyVeloBC()
 {
-	unsigned int mem_size_inflow_BC_INT = sizeof(int)*parameter->getParH()->numberOfVeloBCnodes;
-	unsigned int mem_size_inflow_BC_REAL = sizeof(real)*parameter->getParH()->numberOfVeloBCnodes;
+	unsigned int mem_size_inflow_BC_INT = sizeof(int)*parameter->getParH()->velocityBC.numberOfBCnodes;
+	unsigned int mem_size_inflow_BC_REAL = sizeof(real)*parameter->getParH()->velocityBC.numberOfBCnodes;
 
-	checkCudaErrors( cudaMemcpy(parameter->getParD()->veloBC.q27[0],  parameter->getParH()->veloBC.q27[0], parameter->getD3Qxx() *	mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
-	checkCudaErrors( cudaMemcpy(parameter->getParD()->veloBC.k,       parameter->getParH()->veloBC.k,							    mem_size_inflow_BC_INT ,  cudaMemcpyHostToDevice));
-	checkCudaErrors( cudaMemcpy(parameter->getParD()->veloBC.Vx,      parameter->getParH()->veloBC.Vx,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
-	checkCudaErrors( cudaMemcpy(parameter->getParD()->veloBC.Vy,      parameter->getParH()->veloBC.Vy,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
-	checkCudaErrors( cudaMemcpy(parameter->getParD()->veloBC.Vz,      parameter->getParH()->veloBC.Vz,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->velocityBC.q27[0],  parameter->getParH()->velocityBC.q27[0], parameter->getD3Qxx() *	mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->velocityBC.k,       parameter->getParH()->velocityBC.k,							    mem_size_inflow_BC_INT ,  cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->velocityBC.Vx,      parameter->getParH()->velocityBC.Vx,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->velocityBC.Vy,      parameter->getParH()->velocityBC.Vy,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->velocityBC.Vz,      parameter->getParH()->velocityBC.Vz,								mem_size_inflow_BC_REAL,  cudaMemcpyHostToDevice));
 
 }
 void CudaMemoryManager::cudaFreeVeloBC()
 {
-	checkCudaErrors( cudaFreeHost(parameter->getParH()->veloBC.q27[0] ));
-	checkCudaErrors( cudaFreeHost(parameter->getParH()->veloBC.k      ));
-	checkCudaErrors( cudaFreeHost(parameter->getParH()->veloBC.Vx     ));
-	checkCudaErrors( cudaFreeHost(parameter->getParH()->veloBC.Vy     ));
-	checkCudaErrors( cudaFreeHost(parameter->getParH()->veloBC.Vz     ));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->velocityBC.q27[0] ));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->velocityBC.k      ));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->velocityBC.Vx     ));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->velocityBC.Vy     ));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->velocityBC.Vz     ));
 }
 
+//No-Slip boundary condition
+void CudaMemoryManager::cudaAllocNoSlipBC()
+{
+	unsigned int mem_size_Q_k      = sizeof(int)*parameter->getParH()->noSlipBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q      = sizeof(real)*parameter->getParH()->noSlipBC.numberOfBCnodes;
+	//Host
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->noSlipBC.q27[0]), parameter->getD3Qxx()*mem_size_Q_q      ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->noSlipBC.k),                 mem_size_Q_k      ));
+
+	//Device
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->noSlipBC.q27[0]),     parameter->getD3Qxx()* mem_size_Q_q     ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->noSlipBC.k),                      mem_size_Q_k     ));
 
+	//////////////////////////////////////////////////////////////////////////
+	double tmp = (double)mem_size_Q_k + (double)parameter->getD3Qxx()*(double)mem_size_Q_q;
+	setMemsizeGPU(tmp, false);
+}
+void CudaMemoryManager::cudaCopyNoSlipBC()
+{
+	unsigned int mem_size_Q_k = sizeof(int)*parameter->getParH()->noSlipBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q = sizeof(real)*parameter->getParH()->noSlipBC.numberOfBCnodes;
+
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->noSlipBC.q27[0], parameter->getParH()->noSlipBC.q27[0], parameter->getD3Qxx()* mem_size_Q_q,       cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->noSlipBC.k,      parameter->getParH()->noSlipBC.k,      mem_size_Q_k,       cudaMemcpyHostToDevice));
+}
+void CudaMemoryManager::cudaFreeNoSlipBC()
+{
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->noSlipBC.q27[0]));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->noSlipBC.k));
+}
+// geometry boundary condition
+void CudaMemoryManager::cudaAllocGeomBC()
+{
+	unsigned int mem_size_Q_k      = sizeof(int)*parameter->getParH()->geometryBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q      = sizeof(real)*parameter->getParH()->geometryBC.numberOfBCnodes;
+
+	//Host
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->geometryBC.q27[0]), parameter->getD3Qxx()*mem_size_Q_q      ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->geometryBC.k),                 mem_size_Q_k      ));
+
+	//Device
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->geometryBC.q27[0]),     parameter->getD3Qxx()* mem_size_Q_q     ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->geometryBC.k),                      mem_size_Q_k     ));
+
+	//////////////////////////////////////////////////////////////////////////
+	double tmp = (double)mem_size_Q_k + (double)parameter->getD3Qxx()*(double)mem_size_Q_q;
+	setMemsizeGPU(tmp, false);
+}
+void CudaMemoryManager::cudaCopyGeomBC()
+{
+	unsigned int mem_size_Q_k = sizeof(int)*parameter->getParH()->geometryBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q = sizeof(real)*parameter->getParH()->geometryBC.numberOfBCnodes;
+
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->geometryBC.q27[0], parameter->getParH()->geometryBC.q27[0], parameter->getD3Qxx()* mem_size_Q_q,       cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->geometryBC.k,      parameter->getParH()->geometryBC.k,                  mem_size_Q_k,       cudaMemcpyHostToDevice));
+}
+void CudaMemoryManager::cudaFreeGeomBC()
+{
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->geometryBC.q27[0]));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->geometryBC.k));
+}
+
+// pressure boundary condition
+void CudaMemoryManager::cudaAllocPress()
+{
+	unsigned int mem_size_Q_k      = sizeof(int)*parameter->getParH()->pressureBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q      = sizeof(real)*parameter->getParH()->pressureBC.numberOfBCnodes;
+
+	//Host
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->pressureBC.q27[0]), parameter->getD3Qxx()*mem_size_Q_q      ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->pressureBC.k),                 mem_size_Q_k      ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->pressureBC.kN),                mem_size_Q_k      ));
+	checkCudaErrors( cudaMallocHost((void**) &(parameter->getParH()->pressureBC.RhoBC),             mem_size_Q_q      ));
+
+	//Device
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->pressureBC.q27[0]),     parameter->getD3Qxx()* mem_size_Q_q     ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->pressureBC.k),                      mem_size_Q_k     ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->pressureBC.kN),                     mem_size_Q_k     ));
+	checkCudaErrors( cudaMalloc((void**) &(parameter->getParD()->pressureBC.RhoBC),                  mem_size_Q_q     ));
+
+	//////////////////////////////////////////////////////////////////////////
+	double tmp = 2. * (double)mem_size_Q_k + (double)mem_size_Q_q + (double)parameter->getD3Qxx()*(double)mem_size_Q_q;
+	setMemsizeGPU(tmp, false);
+}
+void CudaMemoryManager::cudaCopyPress()
+{
+	unsigned int mem_size_Q_k = sizeof(int)*parameter->getParH()->pressureBC.numberOfBCnodes;
+	unsigned int mem_size_Q_q = sizeof(real)*parameter->getParH()->pressureBC.numberOfBCnodes;
+
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->pressureBC.q27[0], parameter->getParH()->pressureBC.q27[0], parameter->getD3Qxx()* mem_size_Q_q,       cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->pressureBC.k,      parameter->getParH()->pressureBC.k,                  mem_size_Q_k,       cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->pressureBC.kN,     parameter->getParH()->pressureBC.kN,                 mem_size_Q_k,       cudaMemcpyHostToDevice));
+	checkCudaErrors( cudaMemcpy(parameter->getParD()->pressureBC.RhoBC,  parameter->getParH()->pressureBC.RhoBC,              mem_size_Q_q,       cudaMemcpyHostToDevice));
+}
+void CudaMemoryManager::cudaFreePress()
+{
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->pressureBC.q27[0]));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->pressureBC.k));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->pressureBC.kN));
+	checkCudaErrors( cudaFreeHost(parameter->getParH()->pressureBC.RhoBC));
+}
 
 
 
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
index d0ee51b61143215c75442cdd1845daa4b4904819..cceaaa7fdfbdb72a7dfcdb31dbbb72eb76673623 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
+++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
@@ -81,6 +81,21 @@ public:
 	void cudaAllocVeloBC();
 	void cudaCopyVeloBC();
 	void cudaFreeVeloBC();
+	
+    //! \brief allocate, copy and free the host / device memory for the no slip boundary condition
+	void cudaAllocNoSlipBC();
+	void cudaCopyNoSlipBC();
+	void cudaFreeNoSlipBC();
+
+    //! \brief allocate, copy and free the host / device memory for the geometry boundary condition
+	void cudaAllocGeomBC();
+	void cudaCopyGeomBC();
+	void cudaFreeGeomBC();
+
+    //! \brief allocate, copy and free the host / device memory for the pressure boundary condition
+	void cudaAllocPress();
+	void cudaCopyPress();
+	void cudaFreePress();
 
 	//! \brief allocate, copy and free the host / device memory for the forcing
 	void cudaAllocForcing();
diff --git a/src/gpu/VirtualFluids_GPU/GPU/Cumulant27chim.cu b/src/gpu/VirtualFluids_GPU/GPU/Cumulant27chim.cu
index a08da5ba3f08eecbd1b2c10ce902dc639e846716..a1414b3eedfe2de2c94a7743c96fb4d6e48b36ef 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/Cumulant27chim.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/Cumulant27chim.cu
@@ -32,9 +32,10 @@
 //=======================================================================================
 /* Device code */
 #include "LBM/LB.h"
-#include "LBM/D3Q27.h"
+#include "lbm/constants/D3Q27.h"
 #include <lbm/constants/NumericConstants.h>
 
+using namespace vf::lbm::dir;
 using namespace vf::lbm::constant;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -138,63 +139,63 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel(
 		Distributions27 dist;
 		if (isEvenTimestep)
 		{
-			dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+			dist.f[E   ] = &distributions[E   *size_Mat];
+			dist.f[W   ] = &distributions[W   *size_Mat];
+			dist.f[N   ] = &distributions[N   *size_Mat];
+			dist.f[S   ] = &distributions[S   *size_Mat];
+			dist.f[T   ] = &distributions[T   *size_Mat];
+			dist.f[B   ] = &distributions[B   *size_Mat];
+			dist.f[NE  ] = &distributions[NE  *size_Mat];
+			dist.f[SW  ] = &distributions[SW  *size_Mat];
+			dist.f[SE  ] = &distributions[SE  *size_Mat];
+			dist.f[NW  ] = &distributions[NW  *size_Mat];
+			dist.f[TE  ] = &distributions[TE  *size_Mat];
+			dist.f[BW  ] = &distributions[BW  *size_Mat];
+			dist.f[BE  ] = &distributions[BE  *size_Mat];
+			dist.f[TW  ] = &distributions[TW  *size_Mat];
+			dist.f[TN  ] = &distributions[TN  *size_Mat];
+			dist.f[BS  ] = &distributions[BS  *size_Mat];
+			dist.f[BN  ] = &distributions[BN  *size_Mat];
+			dist.f[TS  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[TNE ] = &distributions[TNE *size_Mat];
+			dist.f[TSW ] = &distributions[TSW *size_Mat];
+			dist.f[TSE ] = &distributions[TSE *size_Mat];
+			dist.f[TNW ] = &distributions[TNW *size_Mat];
+			dist.f[BNE ] = &distributions[BNE *size_Mat];
+			dist.f[BSW ] = &distributions[BSW *size_Mat];
+			dist.f[BSE ] = &distributions[BSE *size_Mat];
+			dist.f[BNW ] = &distributions[BNW *size_Mat];
 		}
 		else
 		{
-			dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
+			dist.f[W   ] = &distributions[E   *size_Mat];
+			dist.f[E   ] = &distributions[W   *size_Mat];
+			dist.f[S   ] = &distributions[N   *size_Mat];
+			dist.f[N   ] = &distributions[S   *size_Mat];
+			dist.f[B   ] = &distributions[T   *size_Mat];
+			dist.f[T   ] = &distributions[B   *size_Mat];
+			dist.f[SW  ] = &distributions[NE  *size_Mat];
+			dist.f[NE  ] = &distributions[SW  *size_Mat];
+			dist.f[NW  ] = &distributions[SE  *size_Mat];
+			dist.f[SE  ] = &distributions[NW  *size_Mat];
+			dist.f[BW  ] = &distributions[TE  *size_Mat];
+			dist.f[TE  ] = &distributions[BW  *size_Mat];
+			dist.f[TW  ] = &distributions[BE  *size_Mat];
+			dist.f[BE  ] = &distributions[TW  *size_Mat];
+			dist.f[BS  ] = &distributions[TN  *size_Mat];
+			dist.f[TN  ] = &distributions[BS  *size_Mat];
+			dist.f[TS  ] = &distributions[BN  *size_Mat];
+			dist.f[BN  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[BSW ] = &distributions[TNE *size_Mat];
+			dist.f[BNE ] = &distributions[TSW *size_Mat];
+			dist.f[BNW ] = &distributions[TSE *size_Mat];
+			dist.f[BSE ] = &distributions[TNW *size_Mat];
+			dist.f[TSW ] = &distributions[BNE *size_Mat];
+			dist.f[TNE ] = &distributions[BSW *size_Mat];
+			dist.f[TNW ] = &distributions[BSE *size_Mat];
+			dist.f[TSE ] = &distributions[BNW *size_Mat];
 		}
 		////////////////////////////////////////////////////////////////////////////////
 		//! - Set neighbor indices (necessary for indirect addressing)
@@ -208,33 +209,33 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel(
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Set local distributions
 		//!
-		real mfcbb = (dist.f[dirE   ])[k];
-		real mfabb = (dist.f[dirW   ])[kw];
-		real mfbcb = (dist.f[dirN   ])[k];
-		real mfbab = (dist.f[dirS   ])[ks];
-		real mfbbc = (dist.f[dirT   ])[k];
-		real mfbba = (dist.f[dirB   ])[kb];
-		real mfccb = (dist.f[dirNE  ])[k];
-		real mfaab = (dist.f[dirSW  ])[ksw];
-		real mfcab = (dist.f[dirSE  ])[ks];
-		real mfacb = (dist.f[dirNW  ])[kw];
-		real mfcbc = (dist.f[dirTE  ])[k];
-		real mfaba = (dist.f[dirBW  ])[kbw];
-		real mfcba = (dist.f[dirBE  ])[kb];
-		real mfabc = (dist.f[dirTW  ])[kw];
-		real mfbcc = (dist.f[dirTN  ])[k];
-		real mfbaa = (dist.f[dirBS  ])[kbs];
-		real mfbca = (dist.f[dirBN  ])[kb];
-		real mfbac = (dist.f[dirTS  ])[ks];
-		real mfbbb = (dist.f[dirREST])[k];
-		real mfccc = (dist.f[dirTNE ])[k];
-		real mfaac = (dist.f[dirTSW ])[ksw];
-		real mfcac = (dist.f[dirTSE ])[ks];
-		real mfacc = (dist.f[dirTNW ])[kw];
-		real mfcca = (dist.f[dirBNE ])[kb];
-		real mfaaa = (dist.f[dirBSW ])[kbsw];
-		real mfcaa = (dist.f[dirBSE ])[kbs];
-		real mfaca = (dist.f[dirBNW ])[kbw];
+		real mfcbb = (dist.f[E   ])[k];
+		real mfabb = (dist.f[W   ])[kw];
+		real mfbcb = (dist.f[N   ])[k];
+		real mfbab = (dist.f[S   ])[ks];
+		real mfbbc = (dist.f[T   ])[k];
+		real mfbba = (dist.f[B   ])[kb];
+		real mfccb = (dist.f[NE  ])[k];
+		real mfaab = (dist.f[SW  ])[ksw];
+		real mfcab = (dist.f[SE  ])[ks];
+		real mfacb = (dist.f[NW  ])[kw];
+		real mfcbc = (dist.f[TE  ])[k];
+		real mfaba = (dist.f[BW  ])[kbw];
+		real mfcba = (dist.f[BE  ])[kb];
+		real mfabc = (dist.f[TW  ])[kw];
+		real mfbcc = (dist.f[TN  ])[k];
+		real mfbaa = (dist.f[BS  ])[kbs];
+		real mfbca = (dist.f[BN  ])[kb];
+		real mfbac = (dist.f[TS  ])[ks];
+		real mfbbb = (dist.f[REST])[k];
+		real mfccc = (dist.f[TNE ])[k];
+		real mfaac = (dist.f[TSW ])[ksw];
+		real mfcac = (dist.f[TSE ])[ks];
+		real mfacc = (dist.f[TNW ])[kw];
+		real mfcca = (dist.f[BNE ])[kb];
+		real mfaaa = (dist.f[BSW ])[kbsw];
+		real mfcaa = (dist.f[BSE ])[kbs];
+		real mfaca = (dist.f[BNW ])[kbw];
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Calculate density and velocity using pyramid summation for low round-off errors as in Eq. (J1)-(J3) \ref
 		//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
@@ -359,8 +360,8 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel(
 		//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
 		//! with simplifications assuming \f$ \omega_2 = 1.0 \f$ (modify for different bulk viscosity).
 		//!
-		real A = (c4o1 + c2o1*omega - c3o1*omega*omega) / (c2o1 - c7o1*omega + c5o1*omega*omega);
-		real B = (c4o1 + c28o1*omega - c14o1*omega*omega) / (c6o1 - c21o1*omega + c15o1*omega*omega);
+		real factorA = (c4o1 + c2o1*omega - c3o1*omega*omega) / (c2o1 - c7o1*omega + c5o1*omega*omega);
+		real factorB = (c4o1 + c28o1*omega - c14o1*omega*omega) / (c6o1 - c21o1*omega + c15o1*omega*omega);
 
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Compute cumulants from central moments according to Eq. (20)-(23) in
@@ -501,12 +502,12 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel(
 		//! - Relax fourth order cumulants to modified equilibrium for fourth order convergence of diffusion according to Eq. (43)-(48)
 		//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
 		//!
-		CUMacc = -O4*(c1o1 / omega - c1o2) * (dyuy + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMacc);
-		CUMcac = -O4*(c1o1 / omega - c1o2) * (dxux + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMcac);
-		CUMcca = -O4*(c1o1 / omega - c1o2) * (dyuy + dxux) * c2o3 * A + (c1o1 - O4) * (CUMcca);
-		CUMbbc = -O4*(c1o1 / omega - c1o2) * Dxy           * c1o3 * B + (c1o1 - O4) * (CUMbbc);
-		CUMbcb = -O4*(c1o1 / omega - c1o2) * Dxz           * c1o3 * B + (c1o1 - O4) * (CUMbcb);
-		CUMcbb = -O4*(c1o1 / omega - c1o2) * Dyz           * c1o3 * B + (c1o1 - O4) * (CUMcbb);
+		CUMacc = -O4*(c1o1 / omega - c1o2) * (dyuy + dzuz) * c2o3 * factorA + (c1o1 - O4) * (CUMacc);
+		CUMcac = -O4*(c1o1 / omega - c1o2) * (dxux + dzuz) * c2o3 * factorA + (c1o1 - O4) * (CUMcac);
+		CUMcca = -O4*(c1o1 / omega - c1o2) * (dyuy + dxux) * c2o3 * factorA + (c1o1 - O4) * (CUMcca);
+		CUMbbc = -O4*(c1o1 / omega - c1o2) * Dxy           * c1o3 * factorB + (c1o1 - O4) * (CUMbbc);
+		CUMbcb = -O4*(c1o1 / omega - c1o2) * Dxz           * c1o3 * factorB + (c1o1 - O4) * (CUMbcb);
+		CUMcbb = -O4*(c1o1 / omega - c1o2) * Dyz           * c1o3 * factorB + (c1o1 - O4) * (CUMcbb);
 
 		//////////////////////////////////////////////////////////////////////////
 		//5.
@@ -610,33 +611,33 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel(
 		//! stored arrays dependent on timestep is based on the esoteric twist algorithm
 		//! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
 		//!
-		(dist.f[dirE   ])[k   ] = mfabb;
-		(dist.f[dirW   ])[kw  ] = mfcbb;
-		(dist.f[dirN   ])[k   ] = mfbab;
-		(dist.f[dirS   ])[ks  ] = mfbcb;
-		(dist.f[dirT   ])[k   ] = mfbba;
-		(dist.f[dirB   ])[kb  ] = mfbbc;
-		(dist.f[dirNE  ])[k   ] = mfaab;
-		(dist.f[dirSW  ])[ksw ] = mfccb;
-		(dist.f[dirSE  ])[ks  ] = mfacb;
-		(dist.f[dirNW  ])[kw  ] = mfcab;
-		(dist.f[dirTE  ])[k   ] = mfaba;
-		(dist.f[dirBW  ])[kbw ] = mfcbc;
-		(dist.f[dirBE  ])[kb  ] = mfabc;
-		(dist.f[dirTW  ])[kw  ] = mfcba;
-		(dist.f[dirTN  ])[k   ] = mfbaa;
-		(dist.f[dirBS  ])[kbs ] = mfbcc;
-		(dist.f[dirBN  ])[kb  ] = mfbac;
-		(dist.f[dirTS  ])[ks  ] = mfbca;
-		(dist.f[dirREST])[k   ] = mfbbb;
-		(dist.f[dirTNE ])[k   ] = mfaaa;
-		(dist.f[dirTSE ])[ks  ] = mfaca;
-		(dist.f[dirBNE ])[kb  ] = mfaac;
-		(dist.f[dirBSE ])[kbs ] = mfacc;
-		(dist.f[dirTNW ])[kw  ] = mfcaa;
-		(dist.f[dirTSW ])[ksw ] = mfcca;
-		(dist.f[dirBNW ])[kbw ] = mfcac;
-		(dist.f[dirBSW ])[kbsw] = mfccc;
+		(dist.f[E   ])[k   ] = mfabb;
+		(dist.f[W   ])[kw  ] = mfcbb;
+		(dist.f[N   ])[k   ] = mfbab;
+		(dist.f[S   ])[ks  ] = mfbcb;
+		(dist.f[T   ])[k   ] = mfbba;
+		(dist.f[B   ])[kb  ] = mfbbc;
+		(dist.f[NE  ])[k   ] = mfaab;
+		(dist.f[SW  ])[ksw ] = mfccb;
+		(dist.f[SE  ])[ks  ] = mfacb;
+		(dist.f[NW  ])[kw  ] = mfcab;
+		(dist.f[TE  ])[k   ] = mfaba;
+		(dist.f[BW  ])[kbw ] = mfcbc;
+		(dist.f[BE  ])[kb  ] = mfabc;
+		(dist.f[TW  ])[kw  ] = mfcba;
+		(dist.f[TN  ])[k   ] = mfbaa;
+		(dist.f[BS  ])[kbs ] = mfbcc;
+		(dist.f[BN  ])[kb  ] = mfbac;
+		(dist.f[TS  ])[ks  ] = mfbca;
+		(dist.f[REST])[k   ] = mfbbb;
+		(dist.f[TNE ])[k   ] = mfaaa;
+		(dist.f[TSE ])[ks  ] = mfaca;
+		(dist.f[BNE ])[kb  ] = mfaac;
+		(dist.f[BSE ])[kbs ] = mfacc;
+		(dist.f[TNW ])[kw  ] = mfcaa;
+		(dist.f[TSW ])[ksw ] = mfcca;
+		(dist.f[BNW ])[kbw ] = mfcac;
+		(dist.f[BSW ])[kbsw] = mfccc;
 	}
 }
 ////////////////////////////////////////////////////////////////////////////////
@@ -709,125 +710,125 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel_AD(
 		Distributions27 dist;
 		if (isEvenTimestep)
 		{
-			dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+			dist.f[E   ] = &distributions[E   *size_Mat];
+			dist.f[W   ] = &distributions[W   *size_Mat];
+			dist.f[N   ] = &distributions[N   *size_Mat];
+			dist.f[S   ] = &distributions[S   *size_Mat];
+			dist.f[T   ] = &distributions[T   *size_Mat];
+			dist.f[B   ] = &distributions[B   *size_Mat];
+			dist.f[NE  ] = &distributions[NE  *size_Mat];
+			dist.f[SW  ] = &distributions[SW  *size_Mat];
+			dist.f[SE  ] = &distributions[SE  *size_Mat];
+			dist.f[NW  ] = &distributions[NW  *size_Mat];
+			dist.f[TE  ] = &distributions[TE  *size_Mat];
+			dist.f[BW  ] = &distributions[BW  *size_Mat];
+			dist.f[BE  ] = &distributions[BE  *size_Mat];
+			dist.f[TW  ] = &distributions[TW  *size_Mat];
+			dist.f[TN  ] = &distributions[TN  *size_Mat];
+			dist.f[BS  ] = &distributions[BS  *size_Mat];
+			dist.f[BN  ] = &distributions[BN  *size_Mat];
+			dist.f[TS  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[TNE ] = &distributions[TNE *size_Mat];
+			dist.f[TSW ] = &distributions[TSW *size_Mat];
+			dist.f[TSE ] = &distributions[TSE *size_Mat];
+			dist.f[TNW ] = &distributions[TNW *size_Mat];
+			dist.f[BNE ] = &distributions[BNE *size_Mat];
+			dist.f[BSW ] = &distributions[BSW *size_Mat];
+			dist.f[BSE ] = &distributions[BSE *size_Mat];
+			dist.f[BNW ] = &distributions[BNW *size_Mat];
 		}
 		else
 		{
-			dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
+			dist.f[W   ] = &distributions[E   *size_Mat];
+			dist.f[E   ] = &distributions[W   *size_Mat];
+			dist.f[S   ] = &distributions[N   *size_Mat];
+			dist.f[N   ] = &distributions[S   *size_Mat];
+			dist.f[B   ] = &distributions[T   *size_Mat];
+			dist.f[T   ] = &distributions[B   *size_Mat];
+			dist.f[SW  ] = &distributions[NE  *size_Mat];
+			dist.f[NE  ] = &distributions[SW  *size_Mat];
+			dist.f[NW  ] = &distributions[SE  *size_Mat];
+			dist.f[SE  ] = &distributions[NW  *size_Mat];
+			dist.f[BW  ] = &distributions[TE  *size_Mat];
+			dist.f[TE  ] = &distributions[BW  *size_Mat];
+			dist.f[TW  ] = &distributions[BE  *size_Mat];
+			dist.f[BE  ] = &distributions[TW  *size_Mat];
+			dist.f[BS  ] = &distributions[TN  *size_Mat];
+			dist.f[TN  ] = &distributions[BS  *size_Mat];
+			dist.f[TS  ] = &distributions[BN  *size_Mat];
+			dist.f[BN  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[BSW ] = &distributions[TNE *size_Mat];
+			dist.f[BNE ] = &distributions[TSW *size_Mat];
+			dist.f[BNW ] = &distributions[TSE *size_Mat];
+			dist.f[BSE ] = &distributions[TNW *size_Mat];
+			dist.f[TSW ] = &distributions[BNE *size_Mat];
+			dist.f[TNE ] = &distributions[BSW *size_Mat];
+			dist.f[TNW ] = &distributions[BSE *size_Mat];
+			dist.f[TSE ] = &distributions[BNW *size_Mat];
 		}
         ////////////////////////////////////////////////////////////////////////////////
         Distributions27 distAD;
         if (isEvenTimestep)
         {
-            distAD.f[dirE   ] = &distributionsAD[dirE   *size_Mat];
-            distAD.f[dirW   ] = &distributionsAD[dirW   *size_Mat];
-            distAD.f[dirN   ] = &distributionsAD[dirN   *size_Mat];
-            distAD.f[dirS   ] = &distributionsAD[dirS   *size_Mat];
-            distAD.f[dirT   ] = &distributionsAD[dirT   *size_Mat];
-            distAD.f[dirB   ] = &distributionsAD[dirB   *size_Mat];
-            distAD.f[dirNE  ] = &distributionsAD[dirNE  *size_Mat];
-            distAD.f[dirSW  ] = &distributionsAD[dirSW  *size_Mat];
-            distAD.f[dirSE  ] = &distributionsAD[dirSE  *size_Mat];
-            distAD.f[dirNW  ] = &distributionsAD[dirNW  *size_Mat];
-            distAD.f[dirTE  ] = &distributionsAD[dirTE  *size_Mat];
-            distAD.f[dirBW  ] = &distributionsAD[dirBW  *size_Mat];
-            distAD.f[dirBE  ] = &distributionsAD[dirBE  *size_Mat];
-            distAD.f[dirTW  ] = &distributionsAD[dirTW  *size_Mat];
-            distAD.f[dirTN  ] = &distributionsAD[dirTN  *size_Mat];
-            distAD.f[dirBS  ] = &distributionsAD[dirBS  *size_Mat];
-            distAD.f[dirBN  ] = &distributionsAD[dirBN  *size_Mat];
-            distAD.f[dirTS  ] = &distributionsAD[dirTS  *size_Mat];
-            distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-            distAD.f[dirTNE ] = &distributionsAD[dirTNE *size_Mat];
-            distAD.f[dirTSW ] = &distributionsAD[dirTSW *size_Mat];
-            distAD.f[dirTSE ] = &distributionsAD[dirTSE *size_Mat];
-            distAD.f[dirTNW ] = &distributionsAD[dirTNW *size_Mat];
-            distAD.f[dirBNE ] = &distributionsAD[dirBNE *size_Mat];
-            distAD.f[dirBSW ] = &distributionsAD[dirBSW *size_Mat];
-            distAD.f[dirBSE ] = &distributionsAD[dirBSE *size_Mat];
-            distAD.f[dirBNW ] = &distributionsAD[dirBNW *size_Mat];
+            distAD.f[E   ] = &distributionsAD[E   *size_Mat];
+            distAD.f[W   ] = &distributionsAD[W   *size_Mat];
+            distAD.f[N   ] = &distributionsAD[N   *size_Mat];
+            distAD.f[S   ] = &distributionsAD[S   *size_Mat];
+            distAD.f[T   ] = &distributionsAD[T   *size_Mat];
+            distAD.f[B   ] = &distributionsAD[B   *size_Mat];
+            distAD.f[NE  ] = &distributionsAD[NE  *size_Mat];
+            distAD.f[SW  ] = &distributionsAD[SW  *size_Mat];
+            distAD.f[SE  ] = &distributionsAD[SE  *size_Mat];
+            distAD.f[NW  ] = &distributionsAD[NW  *size_Mat];
+            distAD.f[TE  ] = &distributionsAD[TE  *size_Mat];
+            distAD.f[BW  ] = &distributionsAD[BW  *size_Mat];
+            distAD.f[BE  ] = &distributionsAD[BE  *size_Mat];
+            distAD.f[TW  ] = &distributionsAD[TW  *size_Mat];
+            distAD.f[TN  ] = &distributionsAD[TN  *size_Mat];
+            distAD.f[BS  ] = &distributionsAD[BS  *size_Mat];
+            distAD.f[BN  ] = &distributionsAD[BN  *size_Mat];
+            distAD.f[TS  ] = &distributionsAD[TS  *size_Mat];
+            distAD.f[REST] = &distributionsAD[REST*size_Mat];
+            distAD.f[TNE ] = &distributionsAD[TNE *size_Mat];
+            distAD.f[TSW ] = &distributionsAD[TSW *size_Mat];
+            distAD.f[TSE ] = &distributionsAD[TSE *size_Mat];
+            distAD.f[TNW ] = &distributionsAD[TNW *size_Mat];
+            distAD.f[BNE ] = &distributionsAD[BNE *size_Mat];
+            distAD.f[BSW ] = &distributionsAD[BSW *size_Mat];
+            distAD.f[BSE ] = &distributionsAD[BSE *size_Mat];
+            distAD.f[BNW ] = &distributionsAD[BNW *size_Mat];
         }
         else
         {
-            distAD.f[dirW   ] = &distributionsAD[dirE   *size_Mat];
-            distAD.f[dirE   ] = &distributionsAD[dirW   *size_Mat];
-            distAD.f[dirS   ] = &distributionsAD[dirN   *size_Mat];
-            distAD.f[dirN   ] = &distributionsAD[dirS   *size_Mat];
-            distAD.f[dirB   ] = &distributionsAD[dirT   *size_Mat];
-            distAD.f[dirT   ] = &distributionsAD[dirB   *size_Mat];
-            distAD.f[dirSW  ] = &distributionsAD[dirNE  *size_Mat];
-            distAD.f[dirNE  ] = &distributionsAD[dirSW  *size_Mat];
-            distAD.f[dirNW  ] = &distributionsAD[dirSE  *size_Mat];
-            distAD.f[dirSE  ] = &distributionsAD[dirNW  *size_Mat];
-            distAD.f[dirBW  ] = &distributionsAD[dirTE  *size_Mat];
-            distAD.f[dirTE  ] = &distributionsAD[dirBW  *size_Mat];
-            distAD.f[dirTW  ] = &distributionsAD[dirBE  *size_Mat];
-            distAD.f[dirBE  ] = &distributionsAD[dirTW  *size_Mat];
-            distAD.f[dirBS  ] = &distributionsAD[dirTN  *size_Mat];
-            distAD.f[dirTN  ] = &distributionsAD[dirBS  *size_Mat];
-            distAD.f[dirTS  ] = &distributionsAD[dirBN  *size_Mat];
-            distAD.f[dirBN  ] = &distributionsAD[dirTS  *size_Mat];
-            distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-            distAD.f[dirBSW ] = &distributionsAD[dirTNE *size_Mat];
-            distAD.f[dirBNE ] = &distributionsAD[dirTSW *size_Mat];
-            distAD.f[dirBNW ] = &distributionsAD[dirTSE *size_Mat];
-            distAD.f[dirBSE ] = &distributionsAD[dirTNW *size_Mat];
-            distAD.f[dirTSW ] = &distributionsAD[dirBNE *size_Mat];
-            distAD.f[dirTNE ] = &distributionsAD[dirBSW *size_Mat];
-            distAD.f[dirTNW ] = &distributionsAD[dirBSE *size_Mat];
-            distAD.f[dirTSE ] = &distributionsAD[dirBNW *size_Mat];
+            distAD.f[W   ] = &distributionsAD[E   *size_Mat];
+            distAD.f[E   ] = &distributionsAD[W   *size_Mat];
+            distAD.f[S   ] = &distributionsAD[N   *size_Mat];
+            distAD.f[N   ] = &distributionsAD[S   *size_Mat];
+            distAD.f[B   ] = &distributionsAD[T   *size_Mat];
+            distAD.f[T   ] = &distributionsAD[B   *size_Mat];
+            distAD.f[SW  ] = &distributionsAD[NE  *size_Mat];
+            distAD.f[NE  ] = &distributionsAD[SW  *size_Mat];
+            distAD.f[NW  ] = &distributionsAD[SE  *size_Mat];
+            distAD.f[SE  ] = &distributionsAD[NW  *size_Mat];
+            distAD.f[BW  ] = &distributionsAD[TE  *size_Mat];
+            distAD.f[TE  ] = &distributionsAD[BW  *size_Mat];
+            distAD.f[TW  ] = &distributionsAD[BE  *size_Mat];
+            distAD.f[BE  ] = &distributionsAD[TW  *size_Mat];
+            distAD.f[BS  ] = &distributionsAD[TN  *size_Mat];
+            distAD.f[TN  ] = &distributionsAD[BS  *size_Mat];
+            distAD.f[TS  ] = &distributionsAD[BN  *size_Mat];
+            distAD.f[BN  ] = &distributionsAD[TS  *size_Mat];
+            distAD.f[REST] = &distributionsAD[REST*size_Mat];
+            distAD.f[BSW ] = &distributionsAD[TNE *size_Mat];
+            distAD.f[BNE ] = &distributionsAD[TSW *size_Mat];
+            distAD.f[BNW ] = &distributionsAD[TSE *size_Mat];
+            distAD.f[BSE ] = &distributionsAD[TNW *size_Mat];
+            distAD.f[TSW ] = &distributionsAD[BNE *size_Mat];
+            distAD.f[TNE ] = &distributionsAD[BSW *size_Mat];
+            distAD.f[TNW ] = &distributionsAD[BSE *size_Mat];
+            distAD.f[TSE ] = &distributionsAD[BNW *size_Mat];
         }
 		////////////////////////////////////////////////////////////////////////////////
 		//! - Set neighbor indices (necessary for indirect addressing)
@@ -841,63 +842,63 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel_AD(
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Set local distributions
 		//!
-		real mfcbb = (dist.f[dirE   ])[k];
-		real mfabb = (dist.f[dirW   ])[kw];
-		real mfbcb = (dist.f[dirN   ])[k];
-		real mfbab = (dist.f[dirS   ])[ks];
-		real mfbbc = (dist.f[dirT   ])[k];
-		real mfbba = (dist.f[dirB   ])[kb];
-		real mfccb = (dist.f[dirNE  ])[k];
-		real mfaab = (dist.f[dirSW  ])[ksw];
-		real mfcab = (dist.f[dirSE  ])[ks];
-		real mfacb = (dist.f[dirNW  ])[kw];
-		real mfcbc = (dist.f[dirTE  ])[k];
-		real mfaba = (dist.f[dirBW  ])[kbw];
-		real mfcba = (dist.f[dirBE  ])[kb];
-		real mfabc = (dist.f[dirTW  ])[kw];
-		real mfbcc = (dist.f[dirTN  ])[k];
-		real mfbaa = (dist.f[dirBS  ])[kbs];
-		real mfbca = (dist.f[dirBN  ])[kb];
-		real mfbac = (dist.f[dirTS  ])[ks];
-		real mfbbb = (dist.f[dirREST])[k];
-		real mfccc = (dist.f[dirTNE ])[k];
-		real mfaac = (dist.f[dirTSW ])[ksw];
-		real mfcac = (dist.f[dirTSE ])[ks];
-		real mfacc = (dist.f[dirTNW ])[kw];
-		real mfcca = (dist.f[dirBNE ])[kb];
-		real mfaaa = (dist.f[dirBSW ])[kbsw];
-		real mfcaa = (dist.f[dirBSE ])[kbs];
-		real mfaca = (dist.f[dirBNW ])[kbw];
+		real mfcbb = (dist.f[E   ])[k];
+		real mfabb = (dist.f[W   ])[kw];
+		real mfbcb = (dist.f[N   ])[k];
+		real mfbab = (dist.f[S   ])[ks];
+		real mfbbc = (dist.f[T   ])[k];
+		real mfbba = (dist.f[B   ])[kb];
+		real mfccb = (dist.f[NE  ])[k];
+		real mfaab = (dist.f[SW  ])[ksw];
+		real mfcab = (dist.f[SE  ])[ks];
+		real mfacb = (dist.f[NW  ])[kw];
+		real mfcbc = (dist.f[TE  ])[k];
+		real mfaba = (dist.f[BW  ])[kbw];
+		real mfcba = (dist.f[BE  ])[kb];
+		real mfabc = (dist.f[TW  ])[kw];
+		real mfbcc = (dist.f[TN  ])[k];
+		real mfbaa = (dist.f[BS  ])[kbs];
+		real mfbca = (dist.f[BN  ])[kb];
+		real mfbac = (dist.f[TS  ])[ks];
+		real mfbbb = (dist.f[REST])[k];
+		real mfccc = (dist.f[TNE ])[k];
+		real mfaac = (dist.f[TSW ])[ksw];
+		real mfcac = (dist.f[TSE ])[ks];
+		real mfacc = (dist.f[TNW ])[kw];
+		real mfcca = (dist.f[BNE ])[kb];
+		real mfaaa = (dist.f[BSW ])[kbsw];
+		real mfcaa = (dist.f[BSE ])[kbs];
+		real mfaca = (dist.f[BNW ])[kbw];
         ////////////////////////////////////////////////////////////////////////////////////
         //! - Set local distributions Advection Diffusion
         //!
-        real fcbb = (distAD.f[dirE   ])[k];
-        real fabb = (distAD.f[dirW   ])[kw];
-        real fbcb = (distAD.f[dirN   ])[k];
-        real fbab = (distAD.f[dirS   ])[ks];
-        real fbbc = (distAD.f[dirT   ])[k];
-        real fbba = (distAD.f[dirB   ])[kb];
-        real fccb = (distAD.f[dirNE  ])[k];
-        real faab = (distAD.f[dirSW  ])[ksw];
-        real fcab = (distAD.f[dirSE  ])[ks];
-        real facb = (distAD.f[dirNW  ])[kw];
-        real fcbc = (distAD.f[dirTE  ])[k];
-        real faba = (distAD.f[dirBW  ])[kbw];
-        real fcba = (distAD.f[dirBE  ])[kb];
-        real fabc = (distAD.f[dirTW  ])[kw];
-        real fbcc = (distAD.f[dirTN  ])[k];
-        real fbaa = (distAD.f[dirBS  ])[kbs];
-        real fbca = (distAD.f[dirBN  ])[kb];
-        real fbac = (distAD.f[dirTS  ])[ks];
-        real fbbb = (distAD.f[dirREST])[k];
-        real fccc = (distAD.f[dirTNE ])[k];
-        real faac = (distAD.f[dirTSW ])[ksw];
-        real fcac = (distAD.f[dirTSE ])[ks];
-        real facc = (distAD.f[dirTNW ])[kw];
-        real fcca = (distAD.f[dirBNE ])[kb];
-        real faaa = (distAD.f[dirBSW ])[kbsw];
-        real fcaa = (distAD.f[dirBSE ])[kbs];
-        real faca = (distAD.f[dirBNW ])[kbw];
+        real fcbb = (distAD.f[E   ])[k];
+        real fabb = (distAD.f[W   ])[kw];
+        real fbcb = (distAD.f[N   ])[k];
+        real fbab = (distAD.f[S   ])[ks];
+        real fbbc = (distAD.f[T   ])[k];
+        real fbba = (distAD.f[B   ])[kb];
+        real fccb = (distAD.f[NE  ])[k];
+        real faab = (distAD.f[SW  ])[ksw];
+        real fcab = (distAD.f[SE  ])[ks];
+        real facb = (distAD.f[NW  ])[kw];
+        real fcbc = (distAD.f[TE  ])[k];
+        real faba = (distAD.f[BW  ])[kbw];
+        real fcba = (distAD.f[BE  ])[kb];
+        real fabc = (distAD.f[TW  ])[kw];
+        real fbcc = (distAD.f[TN  ])[k];
+        real fbaa = (distAD.f[BS  ])[kbs];
+        real fbca = (distAD.f[BN  ])[kb];
+        real fbac = (distAD.f[TS  ])[ks];
+        real fbbb = (distAD.f[REST])[k];
+        real fccc = (distAD.f[TNE ])[k];
+        real faac = (distAD.f[TSW ])[ksw];
+        real fcac = (distAD.f[TSE ])[ks];
+        real facc = (distAD.f[TNW ])[kw];
+        real fcca = (distAD.f[BNE ])[kb];
+        real faaa = (distAD.f[BSW ])[kbsw];
+        real fcaa = (distAD.f[BSE ])[kbs];
+        real faca = (distAD.f[BNW ])[kbw];
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Calculate density and velocity using pyramid summation for low round-off errors as in Eq. (J1)-(J3) \ref
 		//! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
@@ -1029,8 +1030,8 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel_AD(
 		//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
 		//! with simplifications assuming \f$ \omega_2 = 1.0 \f$ (modify for different bulk viscosity).
 		//!
-		real A = (c4o1 + c2o1*omega - c3o1*omega*omega) / (c2o1 - c7o1*omega + c5o1*omega*omega);
-		real B = (c4o1 + c28o1*omega - c14o1*omega*omega) / (c6o1 - c21o1*omega + c15o1*omega*omega);
+		real factorA = (c4o1 + c2o1*omega - c3o1*omega*omega) / (c2o1 - c7o1*omega + c5o1*omega*omega);
+		real factorB = (c4o1 + c28o1*omega - c14o1*omega*omega) / (c6o1 - c21o1*omega + c15o1*omega*omega);
 
 		////////////////////////////////////////////////////////////////////////////////////
 		//! - Compute cumulants from central moments according to Eq. (20)-(23) in
@@ -1171,12 +1172,12 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel_AD(
 		//! - Relax fourth order cumulants to modified equilibrium for fourth order convergence of diffusion according to Eq. (43)-(48)
 		//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
 		//!
-		CUMacc = -O4*(c1o1 / omega - c1o2) * (dyuy + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMacc);
-		CUMcac = -O4*(c1o1 / omega - c1o2) * (dxux + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMcac);
-		CUMcca = -O4*(c1o1 / omega - c1o2) * (dyuy + dxux) * c2o3 * A + (c1o1 - O4) * (CUMcca);
-		CUMbbc = -O4*(c1o1 / omega - c1o2) * Dxy           * c1o3 * B + (c1o1 - O4) * (CUMbbc);
-		CUMbcb = -O4*(c1o1 / omega - c1o2) * Dxz           * c1o3 * B + (c1o1 - O4) * (CUMbcb);
-		CUMcbb = -O4*(c1o1 / omega - c1o2) * Dyz           * c1o3 * B + (c1o1 - O4) * (CUMcbb);
+		CUMacc = -O4*(c1o1 / omega - c1o2) * (dyuy + dzuz) * c2o3 * factorA + (c1o1 - O4) * (CUMacc);
+		CUMcac = -O4*(c1o1 / omega - c1o2) * (dxux + dzuz) * c2o3 * factorA + (c1o1 - O4) * (CUMcac);
+		CUMcca = -O4*(c1o1 / omega - c1o2) * (dyuy + dxux) * c2o3 * factorA + (c1o1 - O4) * (CUMcca);
+		CUMbbc = -O4*(c1o1 / omega - c1o2) * Dxy           * c1o3 * factorB + (c1o1 - O4) * (CUMbbc);
+		CUMbcb = -O4*(c1o1 / omega - c1o2) * Dxz           * c1o3 * factorB + (c1o1 - O4) * (CUMbcb);
+		CUMcbb = -O4*(c1o1 / omega - c1o2) * Dyz           * c1o3 * factorB + (c1o1 - O4) * (CUMcbb);
 
 		//////////////////////////////////////////////////////////////////////////
 		//5.
@@ -1280,33 +1281,33 @@ extern "C" __global__ void Cumulant_K17_LBM_Device_Kernel_AD(
 		//! stored arrays dependent on timestep is based on the esoteric twist algorithm
 		//! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
 		//!
-		(dist.f[dirE   ])[k   ] = mfabb;
-		(dist.f[dirW   ])[kw  ] = mfcbb;
-		(dist.f[dirN   ])[k   ] = mfbab;
-		(dist.f[dirS   ])[ks  ] = mfbcb;
-		(dist.f[dirT   ])[k   ] = mfbba;
-		(dist.f[dirB   ])[kb  ] = mfbbc;
-		(dist.f[dirNE  ])[k   ] = mfaab;
-		(dist.f[dirSW  ])[ksw ] = mfccb;
-		(dist.f[dirSE  ])[ks  ] = mfacb;
-		(dist.f[dirNW  ])[kw  ] = mfcab;
-		(dist.f[dirTE  ])[k   ] = mfaba;
-		(dist.f[dirBW  ])[kbw ] = mfcbc;
-		(dist.f[dirBE  ])[kb  ] = mfabc;
-		(dist.f[dirTW  ])[kw  ] = mfcba;
-		(dist.f[dirTN  ])[k   ] = mfbaa;
-		(dist.f[dirBS  ])[kbs ] = mfbcc;
-		(dist.f[dirBN  ])[kb  ] = mfbac;
-		(dist.f[dirTS  ])[ks  ] = mfbca;
-		(dist.f[dirREST])[k   ] = mfbbb;
-		(dist.f[dirTNE ])[k   ] = mfaaa;
-		(dist.f[dirTSE ])[ks  ] = mfaca;
-		(dist.f[dirBNE ])[kb  ] = mfaac;
-		(dist.f[dirBSE ])[kbs ] = mfacc;
-		(dist.f[dirTNW ])[kw  ] = mfcaa;
-		(dist.f[dirTSW ])[ksw ] = mfcca;
-		(dist.f[dirBNW ])[kbw ] = mfcac;
-		(dist.f[dirBSW ])[kbsw] = mfccc;
+		(dist.f[E   ])[k   ] = mfabb;
+		(dist.f[W   ])[kw  ] = mfcbb;
+		(dist.f[N   ])[k   ] = mfbab;
+		(dist.f[S   ])[ks  ] = mfbcb;
+		(dist.f[T   ])[k   ] = mfbba;
+		(dist.f[B   ])[kb  ] = mfbbc;
+		(dist.f[NE  ])[k   ] = mfaab;
+		(dist.f[SW  ])[ksw ] = mfccb;
+		(dist.f[SE  ])[ks  ] = mfacb;
+		(dist.f[NW  ])[kw  ] = mfcab;
+		(dist.f[TE  ])[k   ] = mfaba;
+		(dist.f[BW  ])[kbw ] = mfcbc;
+		(dist.f[BE  ])[kb  ] = mfabc;
+		(dist.f[TW  ])[kw  ] = mfcba;
+		(dist.f[TN  ])[k   ] = mfbaa;
+		(dist.f[BS  ])[kbs ] = mfbcc;
+		(dist.f[BN  ])[kb  ] = mfbac;
+		(dist.f[TS  ])[ks  ] = mfbca;
+		(dist.f[REST])[k   ] = mfbbb;
+		(dist.f[TNE ])[k   ] = mfaaa;
+		(dist.f[TSE ])[ks  ] = mfaca;
+		(dist.f[BNE ])[kb  ] = mfaac;
+		(dist.f[BSE ])[kbs ] = mfacc;
+		(dist.f[TNW ])[kw  ] = mfcaa;
+		(dist.f[TSW ])[ksw ] = mfcca;
+		(dist.f[BNW ])[kbw ] = mfcac;
+		(dist.f[BSW ])[kbsw] = mfccc;
 	}
 }
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h b/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
index ac4d43ac785e7ae8134d367a3c30b806e8e556c5..a851217a98451d4910520319c0f8e1dea27b691d 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
+++ b/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
@@ -31,6 +31,9 @@
 //! \author Martin Schoenherr
 //=======================================================================================
 #include "LBM/LB.h"
+#include "Parameter/Parameter.h"
+
+struct ParameterStruct;
 
 //////////////////////////////////////////////////////////////////////////
 //! \brief Cumulant LBM kernel
@@ -114,23 +117,26 @@ extern "C" void CalcMacADCompSP27(
 	bool isEvenTimestep);
 
 //////////////////////////////////////////////////////////////////////////
-//! \brief defines the behavior of a velocity boundary condition (plain bounce-back plus velocity)
-extern "C" void QVelDevicePlainBB27(
-	uint numberOfThreads,
-	real* velocityX,
-	real* velocityY,
-	real* velocityZ,
-	real* distributions,
-	int* k_Q, 
-	real* QQ,
-	uint sizeQ,
-	int kQ, 
-	uint* neighborX,
-	uint* neighborY,
-	uint* neighborZ,
-	uint size_Mat, 
-	bool isEvenTimestep);
-	
+// velocity boundary conditions
+extern "C" void QVelDevPlainBB27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+extern "C" void QVelDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+//////////////////////////////////////////////////////////////////////////
+// no-slip boundary conditions
+extern "C" void BBDev27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+extern "C" void QDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+//////////////////////////////////////////////////////////////////////////
+// slip boundary condition
+extern "C" void QSlipDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+//////////////////////////////////////////////////////////////////////////
+// pressure boundary condition
+extern "C" void QPressDevNEQ27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition);
+
+
 
 //////////////////////////////////////////////////////////////////////////
 // Advection Diffusion
@@ -141,7 +147,7 @@ extern "C" void QVelDevicePlainBB27(
 //! \brief Advection Diffusion kernel
 extern "C" void FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
 	uint numberOfThreads,
-	real omegaD,
+	real omegaDiffusivity,
 	uint* typeOfGridNode,
 	uint* neighborX,
 	uint* neighborY,
@@ -154,7 +160,7 @@ extern "C" void FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
 
 //////////////////////////////////////////////////////////////////////////
 //! \brief initialize the Advection Diffusion distribution functions
-extern "C" void InitADdevice(
+extern "C" void InitADDev27(
 	uint numberOfThreads,
 	uint* neighborX,
 	uint* neighborY,
@@ -185,15 +191,15 @@ extern "C" void CalcConcentration27(
 //! \brief defines the behavior of a slip-AD boundary condition
 extern "C" void ADSlipVelDevComp(
 	uint numberOfThreads,
-	real * NormalX,
-	real * NormalY,
-	real * NormalZ,
+	real * normalX,
+	real * normalY,
+	real * normalZ,
 	real * distributions,
 	real * distributionsAD,
 	int* QindexArray,
 	real * Qarrays,
 	uint numberOfQs,
-	real omegaD,
+	real omegaDiffusivity,
 	uint * neighborX,
 	uint * neighborY,
 	uint * neighborZ,
diff --git a/src/gpu/VirtualFluids_GPU/GPU/GPU_Kernels.cuh b/src/gpu/VirtualFluids_GPU/GPU/GPU_Kernels.cuh
index 32cca83ed57dcad805202e0f9e5c0649b5c6e531..37bbe089a97a3977705be408404652434b2f01f7 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/GPU_Kernels.cuh
+++ b/src/gpu/VirtualFluids_GPU/GPU/GPU_Kernels.cuh
@@ -113,22 +113,86 @@ extern "C" __global__ void LBCalcMacADCompSP27(
 	bool isEvenTimestep);
 
 //////////////////////////////////////////////////////////////////////////
-//! \brief \ref QVelDevPlainBB27 : device function for the velocity boundary condition (plain bounce-back + velocity)
-extern "C" __global__ void QVelDevPlainBB27(
+// velocity boundary conditions
+extern "C" __global__ void QVelDevicePlainBB27(
+    real* velocityX,
+    real* velocityY,
+    real* velocityZ,
+    real* distributions,
+    int* subgridDistanceIndices,
+    real* subgridDistances,
+    uint numberOfBCnodes,
+    uint* neighborX,
+    uint* neighborY,
+    uint* neighborZ,
+    uint numberOfLBnodes,
+    bool isEvenTimestep);
+
+extern "C" __global__ void QVelDeviceComp27(
 	real* velocityX,
 	real* velocityY,
 	real* velocityZ,
 	real* distributions,
-	int* k_Q, 
-	real* QQ,
-	uint sizeQ,
-	int kQ, 
-	uint* neighborX,
-	uint* neighborY,
-	uint* neighborZ,
-	uint size_Mat, 
+	int* subgridDistanceIndices,
+	real* subgridDistances,
+	unsigned int numberOfBCnodes,
+	real omega,
+	unsigned int* neighborX,
+	unsigned int* neighborY,
+	unsigned int* neighborZ,
+	unsigned int numberOfLBnodes,
 	bool isEvenTimestep);
 
+// no-slip boundary conditions
+extern "C" __global__ void BBDevice27(
+    real* distributions,
+    int* subgridDistanceIndices,
+    real* subgridDistances,
+    unsigned int numberOfBCnodes,
+    unsigned int* neighborX,
+    unsigned int* neighborY,
+    unsigned int* neighborZ,
+    unsigned int numberOfLBnodes,
+    bool isEvenTimestep);
+
+extern "C" __global__ void QDeviceComp27(
+    real* distributions,
+    int* subgridDistanceIndices,
+    real* subgridDistances,
+    unsigned int numberOfBCnodes,
+    real omega,
+    unsigned int* neighborX,
+    unsigned int* neighborY,
+    unsigned int* neighborZ,
+    unsigned int numberOfLBnodes,
+    bool isEvenTimestep);
+
+// slip boundary conditions
+extern "C" __global__ void QSlipDeviceComp27(
+    real* distributions,
+    int* subgridDistanceIndices,
+    real* subgridDistances,
+    unsigned int numberOfBCnodes,
+    real omega,
+    unsigned int* neighborX,
+    unsigned int* neighborY,
+    unsigned int* neighborZ,
+    unsigned int numberOfLBnodes,
+    bool isEvenTimestep);
+
+// pressure boundary conditions
+extern "C" __global__ void QPressDeviceNEQ27(
+    real* rhoBC,
+    real* distribution,
+    int* bcNodeIndices,
+    int* bcNeighborIndices,
+    int numberOfBCnodes,
+    real omega1,
+    unsigned int* neighborX,
+    unsigned int* neighborY,
+    unsigned int* neighborZ,
+    unsigned int size_Mat,
+    bool isEvenTimestep);
 //////////////////////////////////////////////////////////////////////////
 // Advection Diffusion
 //////////////////////////////////////////////////////////////////////////
@@ -136,7 +200,7 @@ extern "C" __global__ void QVelDevPlainBB27(
 //////////////////////////////////////////////////////////////////////////
 //! \brief \ref Advection_Diffusion_Device_Kernel : Factorized central moments for Advection Diffusion Equation
 extern "C" __global__ void Factorized_Central_Moments_Advection_Diffusion_Device_Kernel(
-	real omegaD,
+	real omegaDiffusivity,
 	uint* typeOfGridNode,
 	uint* neighborX,
 	uint* neighborY,
@@ -177,15 +241,15 @@ extern "C" __global__ void CalcConc27(
 //////////////////////////////////////////////////////////////////////////
 //! \brief \ref AD_SlipVelDeviceComp : device function for the slip-AD boundary condition
 extern "C" __global__ void AD_SlipVelDeviceComp(
-	real * NormalX,
-	real * NormalY,
-	real * NormalZ,
+	real * normalX,
+	real * normalY,
+	real * normalZ,
 	real * distributions,
 	real * distributionsAD,
 	int* QindexArray,
 	real * Qarrays,
 	uint numberOfQs,
-	real omegaD,
+	real omegaDiffusivity,
 	uint * neighborX,
 	uint * neighborY,
 	uint * neighborZ,
diff --git a/src/gpu/VirtualFluids_GPU/GPU/Init27.cu b/src/gpu/VirtualFluids_GPU/GPU/Init27.cu
index 08660a5c52fa0a8df4940f0ecb87696ba92a5c81..f964e8198a61f58ba8a45890b2b20c0f02e60260 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/Init27.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/Init27.cu
@@ -32,10 +32,11 @@
 //=======================================================================================
 /* Device code */
 #include "LBM/LB.h"
-#include "LBM/D3Q27.h"
-#include <lbm/constants/NumericConstants.h>
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
 
 using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
 
 extern "C" __global__ void LBInit(
 	uint* neighborX,
@@ -76,63 +77,63 @@ extern "C" __global__ void LBInit(
 		Distributions27 dist;
 		if (isEvenTimestep)
 		{
-			dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
+			dist.f[E   ] = &distributions[E   *size_Mat];
+			dist.f[W   ] = &distributions[W   *size_Mat];
+			dist.f[N   ] = &distributions[N   *size_Mat];
+			dist.f[S   ] = &distributions[S   *size_Mat];
+			dist.f[T   ] = &distributions[T   *size_Mat];
+			dist.f[B   ] = &distributions[B   *size_Mat];
+			dist.f[NE  ] = &distributions[NE  *size_Mat];
+			dist.f[SW  ] = &distributions[SW  *size_Mat];
+			dist.f[SE  ] = &distributions[SE  *size_Mat];
+			dist.f[NW  ] = &distributions[NW  *size_Mat];
+			dist.f[TE  ] = &distributions[TE  *size_Mat];
+			dist.f[BW  ] = &distributions[BW  *size_Mat];
+			dist.f[BE  ] = &distributions[BE  *size_Mat];
+			dist.f[TW  ] = &distributions[TW  *size_Mat];
+			dist.f[TN  ] = &distributions[TN  *size_Mat];
+			dist.f[BS  ] = &distributions[BS  *size_Mat];
+			dist.f[BN  ] = &distributions[BN  *size_Mat];
+			dist.f[TS  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[TNE ] = &distributions[TNE *size_Mat];
+			dist.f[TSW ] = &distributions[TSW *size_Mat];
+			dist.f[TSE ] = &distributions[TSE *size_Mat];
+			dist.f[TNW ] = &distributions[TNW *size_Mat];
+			dist.f[BNE ] = &distributions[BNE *size_Mat];
+			dist.f[BSW ] = &distributions[BSW *size_Mat];
+			dist.f[BSE ] = &distributions[BSE *size_Mat];
+			dist.f[BNW ] = &distributions[BNW *size_Mat];
 		}
 		else
 		{
-			dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-			dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-			dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-			dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-			dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-			dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-			dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-			dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-			dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-			dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-			dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-			dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-			dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-			dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-			dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-			dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-			dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-			dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-			dist.f[dirREST] = &distributions[dirREST*size_Mat];
-			dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-			dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-			dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-			dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-			dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-			dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-			dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-			dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
+			dist.f[W   ] = &distributions[E   *size_Mat];
+			dist.f[E   ] = &distributions[W   *size_Mat];
+			dist.f[S   ] = &distributions[N   *size_Mat];
+			dist.f[N   ] = &distributions[S   *size_Mat];
+			dist.f[B   ] = &distributions[T   *size_Mat];
+			dist.f[T   ] = &distributions[B   *size_Mat];
+			dist.f[SW  ] = &distributions[NE  *size_Mat];
+			dist.f[NE  ] = &distributions[SW  *size_Mat];
+			dist.f[NW  ] = &distributions[SE  *size_Mat];
+			dist.f[SE  ] = &distributions[NW  *size_Mat];
+			dist.f[BW  ] = &distributions[TE  *size_Mat];
+			dist.f[TE  ] = &distributions[BW  *size_Mat];
+			dist.f[TW  ] = &distributions[BE  *size_Mat];
+			dist.f[BE  ] = &distributions[TW  *size_Mat];
+			dist.f[BS  ] = &distributions[TN  *size_Mat];
+			dist.f[TN  ] = &distributions[BS  *size_Mat];
+			dist.f[TS  ] = &distributions[BN  *size_Mat];
+			dist.f[BN  ] = &distributions[TS  *size_Mat];
+			dist.f[REST] = &distributions[REST*size_Mat];
+			dist.f[BSW ] = &distributions[TNE *size_Mat];
+			dist.f[BNE ] = &distributions[TSW *size_Mat];
+			dist.f[BNW ] = &distributions[TSE *size_Mat];
+			dist.f[BSE ] = &distributions[TNW *size_Mat];
+			dist.f[TSW ] = &distributions[BNE *size_Mat];
+			dist.f[TNE ] = &distributions[BSW *size_Mat];
+			dist.f[TNW ] = &distributions[BSE *size_Mat];
+			dist.f[TSE ] = &distributions[BNW *size_Mat];
 		}
 		//////////////////////////////////////////////////////////////////////////
 		//! - Set local velocities and density
@@ -176,33 +177,33 @@ extern "C" __global__ void LBInit(
 		//!
 		real cu_sq = c3o2*(vx1*vx1 + vx2*vx2 + vx3*vx3);
 
-		(dist.f[dirREST])[kzero] = c8o27* (drho - cu_sq);
-		(dist.f[dirE   ])[ke   ] = c2o27* (drho + c3o1*( vx1            ) + c9o2*( vx1            )*( vx1            ) - cu_sq);
-		(dist.f[dirW   ])[kw   ] = c2o27* (drho + c3o1*(-vx1            ) + c9o2*(-vx1            )*(-vx1            ) - cu_sq);
-		(dist.f[dirN   ])[kn   ] = c2o27* (drho + c3o1*(       vx2      ) + c9o2*(       vx2      )*(       vx2      ) - cu_sq);
-		(dist.f[dirS   ])[ks   ] = c2o27* (drho + c3o1*(     - vx2      ) + c9o2*(     - vx2      )*(     - vx2      ) - cu_sq);
-		(dist.f[dirT   ])[kt   ] = c2o27* (drho + c3o1*(             vx3) + c9o2*(             vx3)*(             vx3) - cu_sq);
-		(dist.f[dirB   ])[kb   ] = c2o27* (drho + c3o1*(            -vx3) + c9o2*(            -vx3)*(            -vx3) - cu_sq);
-		(dist.f[dirNE  ])[kne  ] = c1o54* (drho + c3o1*( vx1 + vx2      ) + c9o2*( vx1 + vx2      )*( vx1 + vx2      ) - cu_sq);
-		(dist.f[dirSW  ])[ksw  ] = c1o54* (drho + c3o1*(-vx1 - vx2      ) + c9o2*(-vx1 - vx2      )*(-vx1 - vx2      ) - cu_sq);
-		(dist.f[dirSE  ])[kse  ] = c1o54* (drho + c3o1*( vx1 - vx2      ) + c9o2*( vx1 - vx2      )*( vx1 - vx2      ) - cu_sq);
-		(dist.f[dirNW  ])[knw  ] = c1o54* (drho + c3o1*(-vx1 + vx2      ) + c9o2*(-vx1 + vx2      )*(-vx1 + vx2      ) - cu_sq);
-		(dist.f[dirTE  ])[kte  ] = c1o54* (drho + c3o1*( vx1       + vx3) + c9o2*( vx1       + vx3)*( vx1       + vx3) - cu_sq);
-		(dist.f[dirBW  ])[kbw  ] = c1o54* (drho + c3o1*(-vx1       - vx3) + c9o2*(-vx1       - vx3)*(-vx1       - vx3) - cu_sq);
-		(dist.f[dirBE  ])[kbe  ] = c1o54* (drho + c3o1*( vx1       - vx3) + c9o2*( vx1       - vx3)*( vx1       - vx3) - cu_sq);
-		(dist.f[dirTW  ])[ktw  ] = c1o54* (drho + c3o1*(-vx1       + vx3) + c9o2*(-vx1       + vx3)*(-vx1       + vx3) - cu_sq);
-		(dist.f[dirTN  ])[ktn  ] = c1o54* (drho + c3o1*(       vx2 + vx3) + c9o2*(       vx2 + vx3)*(       vx2 + vx3) - cu_sq);
-		(dist.f[dirBS  ])[kbs  ] = c1o54* (drho + c3o1*(     - vx2 - vx3) + c9o2*(     - vx2 - vx3)*(     - vx2 - vx3) - cu_sq);
-		(dist.f[dirBN  ])[kbn  ] = c1o54* (drho + c3o1*(       vx2 - vx3) + c9o2*(       vx2 - vx3)*(       vx2 - vx3) - cu_sq);
-		(dist.f[dirTS  ])[kts  ] = c1o54* (drho + c3o1*(     - vx2 + vx3) + c9o2*(     - vx2 + vx3)*(     - vx2 + vx3) - cu_sq);
-		(dist.f[dirTNE ])[ktne ] = c1o216*(drho + c3o1*( vx1 + vx2 + vx3) + c9o2*( vx1 + vx2 + vx3)*( vx1 + vx2 + vx3) - cu_sq);
-		(dist.f[dirBSW ])[kbsw ] = c1o216*(drho + c3o1*(-vx1 - vx2 - vx3) + c9o2*(-vx1 - vx2 - vx3)*(-vx1 - vx2 - vx3) - cu_sq);
-		(dist.f[dirBNE ])[kbne ] = c1o216*(drho + c3o1*( vx1 + vx2 - vx3) + c9o2*( vx1 + vx2 - vx3)*( vx1 + vx2 - vx3) - cu_sq);
-		(dist.f[dirTSW ])[ktsw ] = c1o216*(drho + c3o1*(-vx1 - vx2 + vx3) + c9o2*(-vx1 - vx2 + vx3)*(-vx1 - vx2 + vx3) - cu_sq);
-		(dist.f[dirTSE ])[ktse ] = c1o216*(drho + c3o1*( vx1 - vx2 + vx3) + c9o2*( vx1 - vx2 + vx3)*( vx1 - vx2 + vx3) - cu_sq);
-		(dist.f[dirBNW ])[kbnw ] = c1o216*(drho + c3o1*(-vx1 + vx2 - vx3) + c9o2*(-vx1 + vx2 - vx3)*(-vx1 + vx2 - vx3) - cu_sq);
-		(dist.f[dirBSE ])[kbse ] = c1o216*(drho + c3o1*( vx1 - vx2 - vx3) + c9o2*( vx1 - vx2 - vx3)*( vx1 - vx2 - vx3) - cu_sq);
-		(dist.f[dirTNW ])[ktnw ] = c1o216*(drho + c3o1*(-vx1 + vx2 + vx3) + c9o2*(-vx1 + vx2 + vx3)*(-vx1 + vx2 + vx3) - cu_sq);
+		(dist.f[REST])[kzero] = c8o27* (drho - cu_sq);
+		(dist.f[E   ])[ke   ] = c2o27* (drho + c3o1*( vx1            ) + c9o2*( vx1            )*( vx1            ) - cu_sq);
+		(dist.f[W   ])[kw   ] = c2o27* (drho + c3o1*(-vx1            ) + c9o2*(-vx1            )*(-vx1            ) - cu_sq);
+		(dist.f[N   ])[kn   ] = c2o27* (drho + c3o1*(       vx2      ) + c9o2*(       vx2      )*(       vx2      ) - cu_sq);
+		(dist.f[S   ])[ks   ] = c2o27* (drho + c3o1*(     - vx2      ) + c9o2*(     - vx2      )*(     - vx2      ) - cu_sq);
+		(dist.f[T   ])[kt   ] = c2o27* (drho + c3o1*(             vx3) + c9o2*(             vx3)*(             vx3) - cu_sq);
+		(dist.f[B   ])[kb   ] = c2o27* (drho + c3o1*(            -vx3) + c9o2*(            -vx3)*(            -vx3) - cu_sq);
+		(dist.f[NE  ])[kne  ] = c1o54* (drho + c3o1*( vx1 + vx2      ) + c9o2*( vx1 + vx2      )*( vx1 + vx2      ) - cu_sq);
+		(dist.f[SW  ])[ksw  ] = c1o54* (drho + c3o1*(-vx1 - vx2      ) + c9o2*(-vx1 - vx2      )*(-vx1 - vx2      ) - cu_sq);
+		(dist.f[SE  ])[kse  ] = c1o54* (drho + c3o1*( vx1 - vx2      ) + c9o2*( vx1 - vx2      )*( vx1 - vx2      ) - cu_sq);
+		(dist.f[NW  ])[knw  ] = c1o54* (drho + c3o1*(-vx1 + vx2      ) + c9o2*(-vx1 + vx2      )*(-vx1 + vx2      ) - cu_sq);
+		(dist.f[TE  ])[kte  ] = c1o54* (drho + c3o1*( vx1       + vx3) + c9o2*( vx1       + vx3)*( vx1       + vx3) - cu_sq);
+		(dist.f[BW  ])[kbw  ] = c1o54* (drho + c3o1*(-vx1       - vx3) + c9o2*(-vx1       - vx3)*(-vx1       - vx3) - cu_sq);
+		(dist.f[BE  ])[kbe  ] = c1o54* (drho + c3o1*( vx1       - vx3) + c9o2*( vx1       - vx3)*( vx1       - vx3) - cu_sq);
+		(dist.f[TW  ])[ktw  ] = c1o54* (drho + c3o1*(-vx1       + vx3) + c9o2*(-vx1       + vx3)*(-vx1       + vx3) - cu_sq);
+		(dist.f[TN  ])[ktn  ] = c1o54* (drho + c3o1*(       vx2 + vx3) + c9o2*(       vx2 + vx3)*(       vx2 + vx3) - cu_sq);
+		(dist.f[BS  ])[kbs  ] = c1o54* (drho + c3o1*(     - vx2 - vx3) + c9o2*(     - vx2 - vx3)*(     - vx2 - vx3) - cu_sq);
+		(dist.f[BN  ])[kbn  ] = c1o54* (drho + c3o1*(       vx2 - vx3) + c9o2*(       vx2 - vx3)*(       vx2 - vx3) - cu_sq);
+		(dist.f[TS  ])[kts  ] = c1o54* (drho + c3o1*(     - vx2 + vx3) + c9o2*(     - vx2 + vx3)*(     - vx2 + vx3) - cu_sq);
+		(dist.f[TNE ])[ktne ] = c1o216*(drho + c3o1*( vx1 + vx2 + vx3) + c9o2*( vx1 + vx2 + vx3)*( vx1 + vx2 + vx3) - cu_sq);
+		(dist.f[BSW ])[kbsw ] = c1o216*(drho + c3o1*(-vx1 - vx2 - vx3) + c9o2*(-vx1 - vx2 - vx3)*(-vx1 - vx2 - vx3) - cu_sq);
+		(dist.f[BNE ])[kbne ] = c1o216*(drho + c3o1*( vx1 + vx2 - vx3) + c9o2*( vx1 + vx2 - vx3)*( vx1 + vx2 - vx3) - cu_sq);
+		(dist.f[TSW ])[ktsw ] = c1o216*(drho + c3o1*(-vx1 - vx2 + vx3) + c9o2*(-vx1 - vx2 + vx3)*(-vx1 - vx2 + vx3) - cu_sq);
+		(dist.f[TSE ])[ktse ] = c1o216*(drho + c3o1*( vx1 - vx2 + vx3) + c9o2*( vx1 - vx2 + vx3)*( vx1 - vx2 + vx3) - cu_sq);
+		(dist.f[BNW ])[kbnw ] = c1o216*(drho + c3o1*(-vx1 + vx2 - vx3) + c9o2*(-vx1 + vx2 - vx3)*(-vx1 + vx2 - vx3) - cu_sq);
+		(dist.f[BSE ])[kbse ] = c1o216*(drho + c3o1*( vx1 - vx2 - vx3) + c9o2*( vx1 - vx2 - vx3)*( vx1 - vx2 - vx3) - cu_sq);
+		(dist.f[TNW ])[ktnw ] = c1o216*(drho + c3o1*(-vx1 + vx2 + vx3) + c9o2*(-vx1 + vx2 + vx3)*(-vx1 + vx2 + vx3) - cu_sq);
 	}
 }
 
diff --git a/src/gpu/VirtualFluids_GPU/GPU/InitAdvectionDiffusion27.cu b/src/gpu/VirtualFluids_GPU/GPU/InitAdvectionDiffusion27.cu
index d52d7f8e2b598d53c733dc6434d32be9c36512bf..9f1fd247cbc5824d71bd38e70536c9d72c85bed9 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/InitAdvectionDiffusion27.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/InitAdvectionDiffusion27.cu
@@ -32,10 +32,11 @@
 //=======================================================================================
 /* Device code */
 #include "LBM/LB.h"
-#include "LBM/D3Q27.h"
+#include "lbm/constants/D3Q27.h"
 #include <lbm/constants/NumericConstants.h>
 
 using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
 
 extern "C" __global__ void InitAD(
 	uint* neighborX,
@@ -76,63 +77,63 @@ extern "C" __global__ void InitAD(
 		Distributions27 distAD;
 		if (isEvenTimestep)
 		{
-			distAD.f[dirE   ] = &distributionsAD[dirE   *size_Mat];
-			distAD.f[dirW   ] = &distributionsAD[dirW   *size_Mat];
-			distAD.f[dirN   ] = &distributionsAD[dirN   *size_Mat];
-			distAD.f[dirS   ] = &distributionsAD[dirS   *size_Mat];
-			distAD.f[dirT   ] = &distributionsAD[dirT   *size_Mat];
-			distAD.f[dirB   ] = &distributionsAD[dirB   *size_Mat];
-			distAD.f[dirNE  ] = &distributionsAD[dirNE  *size_Mat];
-			distAD.f[dirSW  ] = &distributionsAD[dirSW  *size_Mat];
-			distAD.f[dirSE  ] = &distributionsAD[dirSE  *size_Mat];
-			distAD.f[dirNW  ] = &distributionsAD[dirNW  *size_Mat];
-			distAD.f[dirTE  ] = &distributionsAD[dirTE  *size_Mat];
-			distAD.f[dirBW  ] = &distributionsAD[dirBW  *size_Mat];
-			distAD.f[dirBE  ] = &distributionsAD[dirBE  *size_Mat];
-			distAD.f[dirTW  ] = &distributionsAD[dirTW  *size_Mat];
-			distAD.f[dirTN  ] = &distributionsAD[dirTN  *size_Mat];
-			distAD.f[dirBS  ] = &distributionsAD[dirBS  *size_Mat];
-			distAD.f[dirBN  ] = &distributionsAD[dirBN  *size_Mat];
-			distAD.f[dirTS  ] = &distributionsAD[dirTS  *size_Mat];
-			distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-			distAD.f[dirTNE ] = &distributionsAD[dirTNE *size_Mat];
-			distAD.f[dirTSW ] = &distributionsAD[dirTSW *size_Mat];
-			distAD.f[dirTSE ] = &distributionsAD[dirTSE *size_Mat];
-			distAD.f[dirTNW ] = &distributionsAD[dirTNW *size_Mat];
-			distAD.f[dirBNE ] = &distributionsAD[dirBNE *size_Mat];
-			distAD.f[dirBSW ] = &distributionsAD[dirBSW *size_Mat];
-			distAD.f[dirBSE ] = &distributionsAD[dirBSE *size_Mat];
-			distAD.f[dirBNW ] = &distributionsAD[dirBNW *size_Mat];
+			distAD.f[E   ] = &distributionsAD[E   *size_Mat];
+			distAD.f[W   ] = &distributionsAD[W   *size_Mat];
+			distAD.f[N   ] = &distributionsAD[N   *size_Mat];
+			distAD.f[S   ] = &distributionsAD[S   *size_Mat];
+			distAD.f[T   ] = &distributionsAD[T   *size_Mat];
+			distAD.f[B   ] = &distributionsAD[B   *size_Mat];
+			distAD.f[NE  ] = &distributionsAD[NE  *size_Mat];
+			distAD.f[SW  ] = &distributionsAD[SW  *size_Mat];
+			distAD.f[SE  ] = &distributionsAD[SE  *size_Mat];
+			distAD.f[NW  ] = &distributionsAD[NW  *size_Mat];
+			distAD.f[TE  ] = &distributionsAD[TE  *size_Mat];
+			distAD.f[BW  ] = &distributionsAD[BW  *size_Mat];
+			distAD.f[BE  ] = &distributionsAD[BE  *size_Mat];
+			distAD.f[TW  ] = &distributionsAD[TW  *size_Mat];
+			distAD.f[TN  ] = &distributionsAD[TN  *size_Mat];
+			distAD.f[BS  ] = &distributionsAD[BS  *size_Mat];
+			distAD.f[BN  ] = &distributionsAD[BN  *size_Mat];
+			distAD.f[TS  ] = &distributionsAD[TS  *size_Mat];
+			distAD.f[REST] = &distributionsAD[REST*size_Mat];
+			distAD.f[TNE ] = &distributionsAD[TNE *size_Mat];
+			distAD.f[TSW ] = &distributionsAD[TSW *size_Mat];
+			distAD.f[TSE ] = &distributionsAD[TSE *size_Mat];
+			distAD.f[TNW ] = &distributionsAD[TNW *size_Mat];
+			distAD.f[BNE ] = &distributionsAD[BNE *size_Mat];
+			distAD.f[BSW ] = &distributionsAD[BSW *size_Mat];
+			distAD.f[BSE ] = &distributionsAD[BSE *size_Mat];
+			distAD.f[BNW ] = &distributionsAD[BNW *size_Mat];
 		}
 		else
 		{
-			distAD.f[dirW   ] = &distributionsAD[dirE   *size_Mat];
-			distAD.f[dirE   ] = &distributionsAD[dirW   *size_Mat];
-			distAD.f[dirS   ] = &distributionsAD[dirN   *size_Mat];
-			distAD.f[dirN   ] = &distributionsAD[dirS   *size_Mat];
-			distAD.f[dirB   ] = &distributionsAD[dirT   *size_Mat];
-			distAD.f[dirT   ] = &distributionsAD[dirB   *size_Mat];
-			distAD.f[dirSW  ] = &distributionsAD[dirNE  *size_Mat];
-			distAD.f[dirNE  ] = &distributionsAD[dirSW  *size_Mat];
-			distAD.f[dirNW  ] = &distributionsAD[dirSE  *size_Mat];
-			distAD.f[dirSE  ] = &distributionsAD[dirNW  *size_Mat];
-			distAD.f[dirBW  ] = &distributionsAD[dirTE  *size_Mat];
-			distAD.f[dirTE  ] = &distributionsAD[dirBW  *size_Mat];
-			distAD.f[dirTW  ] = &distributionsAD[dirBE  *size_Mat];
-			distAD.f[dirBE  ] = &distributionsAD[dirTW  *size_Mat];
-			distAD.f[dirBS  ] = &distributionsAD[dirTN  *size_Mat];
-			distAD.f[dirTN  ] = &distributionsAD[dirBS  *size_Mat];
-			distAD.f[dirTS  ] = &distributionsAD[dirBN  *size_Mat];
-			distAD.f[dirBN  ] = &distributionsAD[dirTS  *size_Mat];
-			distAD.f[dirREST] = &distributionsAD[dirREST*size_Mat];
-			distAD.f[dirBSW ] = &distributionsAD[dirTNE *size_Mat];
-			distAD.f[dirBNE ] = &distributionsAD[dirTSW *size_Mat];
-			distAD.f[dirBNW ] = &distributionsAD[dirTSE *size_Mat];
-			distAD.f[dirBSE ] = &distributionsAD[dirTNW *size_Mat];
-			distAD.f[dirTSW ] = &distributionsAD[dirBNE *size_Mat];
-			distAD.f[dirTNE ] = &distributionsAD[dirBSW *size_Mat];
-			distAD.f[dirTNW ] = &distributionsAD[dirBSE *size_Mat];
-			distAD.f[dirTSE ] = &distributionsAD[dirBNW *size_Mat];
+			distAD.f[W   ] = &distributionsAD[E   *size_Mat];
+			distAD.f[E   ] = &distributionsAD[W   *size_Mat];
+			distAD.f[S   ] = &distributionsAD[N   *size_Mat];
+			distAD.f[N   ] = &distributionsAD[S   *size_Mat];
+			distAD.f[B   ] = &distributionsAD[T   *size_Mat];
+			distAD.f[T   ] = &distributionsAD[B   *size_Mat];
+			distAD.f[SW  ] = &distributionsAD[NE  *size_Mat];
+			distAD.f[NE  ] = &distributionsAD[SW  *size_Mat];
+			distAD.f[NW  ] = &distributionsAD[SE  *size_Mat];
+			distAD.f[SE  ] = &distributionsAD[NW  *size_Mat];
+			distAD.f[BW  ] = &distributionsAD[TE  *size_Mat];
+			distAD.f[TE  ] = &distributionsAD[BW  *size_Mat];
+			distAD.f[TW  ] = &distributionsAD[BE  *size_Mat];
+			distAD.f[BE  ] = &distributionsAD[TW  *size_Mat];
+			distAD.f[BS  ] = &distributionsAD[TN  *size_Mat];
+			distAD.f[TN  ] = &distributionsAD[BS  *size_Mat];
+			distAD.f[TS  ] = &distributionsAD[BN  *size_Mat];
+			distAD.f[BN  ] = &distributionsAD[TS  *size_Mat];
+			distAD.f[REST] = &distributionsAD[REST*size_Mat];
+			distAD.f[BSW ] = &distributionsAD[TNE *size_Mat];
+			distAD.f[BNE ] = &distributionsAD[TSW *size_Mat];
+			distAD.f[BNW ] = &distributionsAD[TSE *size_Mat];
+			distAD.f[BSE ] = &distributionsAD[TNW *size_Mat];
+			distAD.f[TSW ] = &distributionsAD[BNE *size_Mat];
+			distAD.f[TNE ] = &distributionsAD[BSW *size_Mat];
+			distAD.f[TNW ] = &distributionsAD[BSE *size_Mat];
+			distAD.f[TSE ] = &distributionsAD[BNW *size_Mat];
 		}
 		//////////////////////////////////////////////////////////////////////////
 		//! - Set local velocities and concetration
@@ -176,33 +177,33 @@ extern "C" __global__ void InitAD(
 		//!
 		real cu_sq = c3o2*(vx1*vx1 + vx2*vx2 + vx3*vx3);
 
-		(distAD.f[dirREST])[kzero] = c8o27  * conc * (c1o1 - cu_sq);
-		(distAD.f[dirE   ])[ke   ] = c2o27  * conc * (c1o1 + c3o1 * ( vx1            ) + c9o2 * ( vx1            ) * ( vx1            ) - cu_sq);
-		(distAD.f[dirW   ])[kw   ] = c2o27  * conc * (c1o1 + c3o1 * (-vx1            ) + c9o2 * (-vx1            ) * (-vx1            ) - cu_sq);
-		(distAD.f[dirN   ])[kn   ] = c2o27  * conc * (c1o1 + c3o1 * (       vx2      ) + c9o2 * (       vx2      ) * (       vx2      ) - cu_sq);
-		(distAD.f[dirS   ])[ks   ] = c2o27  * conc * (c1o1 + c3o1 * (     - vx2      ) + c9o2 * (     - vx2      ) * (     - vx2      ) - cu_sq);
-		(distAD.f[dirT   ])[kt   ] = c2o27  * conc * (c1o1 + c3o1 * (             vx3) + c9o2 * (             vx3) * (             vx3) - cu_sq);
-		(distAD.f[dirB   ])[kb   ] = c2o27  * conc * (c1o1 + c3o1 * (           - vx3) + c9o2 * (           - vx3) * (           - vx3) - cu_sq);
-		(distAD.f[dirNE  ])[kne  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1 + vx2      ) + c9o2 * ( vx1 + vx2      ) * ( vx1 + vx2      ) - cu_sq);
-		(distAD.f[dirSW  ])[ksw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1 - vx2      ) + c9o2 * (-vx1 - vx2      ) * (-vx1 - vx2      ) - cu_sq);
-		(distAD.f[dirSE  ])[kse  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1 - vx2      ) + c9o2 * ( vx1 - vx2      ) * ( vx1 - vx2      ) - cu_sq);
-		(distAD.f[dirNW  ])[knw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1 + vx2      ) + c9o2 * (-vx1 + vx2      ) * (-vx1 + vx2      ) - cu_sq);
-		(distAD.f[dirTE  ])[kte  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1       + vx3) + c9o2 * ( vx1       + vx3) * ( vx1       + vx3) - cu_sq);
-		(distAD.f[dirBW  ])[kbw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1       - vx3) + c9o2 * (-vx1       - vx3) * (-vx1       - vx3) - cu_sq);
-		(distAD.f[dirBE  ])[kbe  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1       - vx3) + c9o2 * ( vx1       - vx3) * ( vx1       - vx3) - cu_sq);
-		(distAD.f[dirTW  ])[ktw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1       + vx3) + c9o2 * (-vx1       + vx3) * (-vx1       + vx3) - cu_sq);
-		(distAD.f[dirTN  ])[ktn  ] = c1o54  * conc * (c1o1 + c3o1 * (       vx2 + vx3) + c9o2 * (       vx2 + vx3) * (       vx2 + vx3) - cu_sq);
-		(distAD.f[dirBS  ])[kbs  ] = c1o54  * conc * (c1o1 + c3o1 * (     - vx2 - vx3) + c9o2 * (     - vx2 - vx3) * (     - vx2 - vx3) - cu_sq);
-		(distAD.f[dirBN  ])[kbn  ] = c1o54  * conc * (c1o1 + c3o1 * (       vx2 - vx3) + c9o2 * (       vx2 - vx3) * (       vx2 - vx3) - cu_sq);
-		(distAD.f[dirTS  ])[kts  ] = c1o54  * conc * (c1o1 + c3o1 * (     - vx2 + vx3) + c9o2 * (     - vx2 + vx3) * (     - vx2 + vx3) - cu_sq);
-		(distAD.f[dirTNE ])[ktne ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 + vx2 + vx3) + c9o2 * ( vx1 + vx2 + vx3) * ( vx1 + vx2 + vx3) - cu_sq);
-		(distAD.f[dirBSW ])[kbsw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 - vx2 - vx3) + c9o2 * (-vx1 - vx2 - vx3) * (-vx1 - vx2 - vx3) - cu_sq);
-		(distAD.f[dirBNE ])[kbne ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 + vx2 - vx3) + c9o2 * ( vx1 + vx2 - vx3) * ( vx1 + vx2 - vx3) - cu_sq);
-		(distAD.f[dirTSW ])[ktsw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 - vx2 + vx3) + c9o2 * (-vx1 - vx2 + vx3) * (-vx1 - vx2 + vx3) - cu_sq);
-		(distAD.f[dirTSE ])[ktse ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 - vx2 + vx3) + c9o2 * ( vx1 - vx2 + vx3) * ( vx1 - vx2 + vx3) - cu_sq);
-		(distAD.f[dirBNW ])[kbnw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 + vx2 - vx3) + c9o2 * (-vx1 + vx2 - vx3) * (-vx1 + vx2 - vx3) - cu_sq);
-		(distAD.f[dirBSE ])[kbse ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 - vx2 - vx3) + c9o2 * ( vx1 - vx2 - vx3) * ( vx1 - vx2 - vx3) - cu_sq);
-		(distAD.f[dirTNW ])[ktnw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 + vx2 + vx3) + c9o2 * (-vx1 + vx2 + vx3) * (-vx1 + vx2 + vx3) - cu_sq);
+		(distAD.f[REST])[kzero] = c8o27  * conc * (c1o1 - cu_sq);
+		(distAD.f[E   ])[ke   ] = c2o27  * conc * (c1o1 + c3o1 * ( vx1            ) + c9o2 * ( vx1            ) * ( vx1            ) - cu_sq);
+		(distAD.f[W   ])[kw   ] = c2o27  * conc * (c1o1 + c3o1 * (-vx1            ) + c9o2 * (-vx1            ) * (-vx1            ) - cu_sq);
+		(distAD.f[N   ])[kn   ] = c2o27  * conc * (c1o1 + c3o1 * (       vx2      ) + c9o2 * (       vx2      ) * (       vx2      ) - cu_sq);
+		(distAD.f[S   ])[ks   ] = c2o27  * conc * (c1o1 + c3o1 * (     - vx2      ) + c9o2 * (     - vx2      ) * (     - vx2      ) - cu_sq);
+		(distAD.f[T   ])[kt   ] = c2o27  * conc * (c1o1 + c3o1 * (             vx3) + c9o2 * (             vx3) * (             vx3) - cu_sq);
+		(distAD.f[B   ])[kb   ] = c2o27  * conc * (c1o1 + c3o1 * (           - vx3) + c9o2 * (           - vx3) * (           - vx3) - cu_sq);
+		(distAD.f[NE  ])[kne  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1 + vx2      ) + c9o2 * ( vx1 + vx2      ) * ( vx1 + vx2      ) - cu_sq);
+		(distAD.f[SW  ])[ksw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1 - vx2      ) + c9o2 * (-vx1 - vx2      ) * (-vx1 - vx2      ) - cu_sq);
+		(distAD.f[SE  ])[kse  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1 - vx2      ) + c9o2 * ( vx1 - vx2      ) * ( vx1 - vx2      ) - cu_sq);
+		(distAD.f[NW  ])[knw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1 + vx2      ) + c9o2 * (-vx1 + vx2      ) * (-vx1 + vx2      ) - cu_sq);
+		(distAD.f[TE  ])[kte  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1       + vx3) + c9o2 * ( vx1       + vx3) * ( vx1       + vx3) - cu_sq);
+		(distAD.f[BW  ])[kbw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1       - vx3) + c9o2 * (-vx1       - vx3) * (-vx1       - vx3) - cu_sq);
+		(distAD.f[BE  ])[kbe  ] = c1o54  * conc * (c1o1 + c3o1 * ( vx1       - vx3) + c9o2 * ( vx1       - vx3) * ( vx1       - vx3) - cu_sq);
+		(distAD.f[TW  ])[ktw  ] = c1o54  * conc * (c1o1 + c3o1 * (-vx1       + vx3) + c9o2 * (-vx1       + vx3) * (-vx1       + vx3) - cu_sq);
+		(distAD.f[TN  ])[ktn  ] = c1o54  * conc * (c1o1 + c3o1 * (       vx2 + vx3) + c9o2 * (       vx2 + vx3) * (       vx2 + vx3) - cu_sq);
+		(distAD.f[BS  ])[kbs  ] = c1o54  * conc * (c1o1 + c3o1 * (     - vx2 - vx3) + c9o2 * (     - vx2 - vx3) * (     - vx2 - vx3) - cu_sq);
+		(distAD.f[BN  ])[kbn  ] = c1o54  * conc * (c1o1 + c3o1 * (       vx2 - vx3) + c9o2 * (       vx2 - vx3) * (       vx2 - vx3) - cu_sq);
+		(distAD.f[TS  ])[kts  ] = c1o54  * conc * (c1o1 + c3o1 * (     - vx2 + vx3) + c9o2 * (     - vx2 + vx3) * (     - vx2 + vx3) - cu_sq);
+		(distAD.f[TNE ])[ktne ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 + vx2 + vx3) + c9o2 * ( vx1 + vx2 + vx3) * ( vx1 + vx2 + vx3) - cu_sq);
+		(distAD.f[BSW ])[kbsw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 - vx2 - vx3) + c9o2 * (-vx1 - vx2 - vx3) * (-vx1 - vx2 - vx3) - cu_sq);
+		(distAD.f[BNE ])[kbne ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 + vx2 - vx3) + c9o2 * ( vx1 + vx2 - vx3) * ( vx1 + vx2 - vx3) - cu_sq);
+		(distAD.f[TSW ])[ktsw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 - vx2 + vx3) + c9o2 * (-vx1 - vx2 + vx3) * (-vx1 - vx2 + vx3) - cu_sq);
+		(distAD.f[TSE ])[ktse ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 - vx2 + vx3) + c9o2 * ( vx1 - vx2 + vx3) * ( vx1 - vx2 + vx3) - cu_sq);
+		(distAD.f[BNW ])[kbnw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 + vx2 - vx3) + c9o2 * (-vx1 + vx2 - vx3) * (-vx1 + vx2 - vx3) - cu_sq);
+		(distAD.f[BSE ])[kbse ] = c1o216 * conc * (c1o1 + c3o1 * ( vx1 - vx2 - vx3) + c9o2 * ( vx1 - vx2 - vx3) * ( vx1 - vx2 - vx3) - cu_sq);
+		(distAD.f[TNW ])[ktnw ] = c1o216 * conc * (c1o1 + c3o1 * (-vx1 + vx2 + vx3) + c9o2 * (-vx1 + vx2 + vx3) * (-vx1 + vx2 + vx3) - cu_sq);
 	}
 }
 
diff --git a/src/gpu/VirtualFluids_GPU/GPU/KernelUtilities.h b/src/gpu/VirtualFluids_GPU/GPU/KernelUtilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..34082639e496aee4e3335dcc753aa7bc9e105cd0
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/GPU/KernelUtilities.h
@@ -0,0 +1,170 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file KernelUtilities.h
+//! \ingroup GPU
+//! \author Martin Schoenherr, Anna Wellmann
+//======================================================================================
+#ifndef KERNELUTILS_H
+#define KERNELUTILS_H
+
+#include "LBM/LB.h"
+#include "lbm/constants/D3Q27.h"
+#include "lbm/constants/NumericConstants.h"
+
+using namespace vf::lbm::constant;
+using namespace vf::lbm::dir;
+
+__inline__ __device__ void getPointersToDistributions(Distributions27 &dist, real *distributionArray, const uint numberOfLBnodes, const bool isEvenTimestep)
+{
+    if (isEvenTimestep)
+    {
+        dist.f[E   ] = &distributionArray[E   *numberOfLBnodes];
+        dist.f[W   ] = &distributionArray[W   *numberOfLBnodes];
+        dist.f[N   ] = &distributionArray[N   *numberOfLBnodes];
+        dist.f[S   ] = &distributionArray[S   *numberOfLBnodes];
+        dist.f[T   ] = &distributionArray[T   *numberOfLBnodes];
+        dist.f[B   ] = &distributionArray[B   *numberOfLBnodes];
+        dist.f[NE  ] = &distributionArray[NE  *numberOfLBnodes];
+        dist.f[SW  ] = &distributionArray[SW  *numberOfLBnodes];
+        dist.f[SE  ] = &distributionArray[SE  *numberOfLBnodes];
+        dist.f[NW  ] = &distributionArray[NW  *numberOfLBnodes];
+        dist.f[TE  ] = &distributionArray[TE  *numberOfLBnodes];
+        dist.f[BW  ] = &distributionArray[BW  *numberOfLBnodes];
+        dist.f[BE  ] = &distributionArray[BE  *numberOfLBnodes];
+        dist.f[TW  ] = &distributionArray[TW  *numberOfLBnodes];
+        dist.f[TN  ] = &distributionArray[TN  *numberOfLBnodes];
+        dist.f[BS  ] = &distributionArray[BS  *numberOfLBnodes];
+        dist.f[BN  ] = &distributionArray[BN  *numberOfLBnodes];
+        dist.f[TS  ] = &distributionArray[TS  *numberOfLBnodes];
+        dist.f[REST] = &distributionArray[REST*numberOfLBnodes];
+        dist.f[TNE ] = &distributionArray[TNE *numberOfLBnodes];
+        dist.f[TSW ] = &distributionArray[TSW *numberOfLBnodes];
+        dist.f[TSE ] = &distributionArray[TSE *numberOfLBnodes];
+        dist.f[TNW ] = &distributionArray[TNW *numberOfLBnodes];
+        dist.f[BNE ] = &distributionArray[BNE *numberOfLBnodes];
+        dist.f[BSW ] = &distributionArray[BSW *numberOfLBnodes];
+        dist.f[BSE ] = &distributionArray[BSE *numberOfLBnodes];
+        dist.f[BNW ] = &distributionArray[BNW *numberOfLBnodes];
+    }
+    else
+    {
+         dist.f[W   ] = &distributionArray[E   *numberOfLBnodes];
+         dist.f[E   ] = &distributionArray[W   *numberOfLBnodes];
+         dist.f[S   ] = &distributionArray[N   *numberOfLBnodes];
+         dist.f[N   ] = &distributionArray[S   *numberOfLBnodes];
+         dist.f[B   ] = &distributionArray[T   *numberOfLBnodes];
+         dist.f[T   ] = &distributionArray[B   *numberOfLBnodes];
+         dist.f[SW  ] = &distributionArray[NE  *numberOfLBnodes];
+         dist.f[NE  ] = &distributionArray[SW  *numberOfLBnodes];
+         dist.f[NW  ] = &distributionArray[SE  *numberOfLBnodes];
+         dist.f[SE  ] = &distributionArray[NW  *numberOfLBnodes];
+         dist.f[BW  ] = &distributionArray[TE  *numberOfLBnodes];
+         dist.f[TE  ] = &distributionArray[BW  *numberOfLBnodes];
+         dist.f[TW  ] = &distributionArray[BE  *numberOfLBnodes];
+         dist.f[BE  ] = &distributionArray[TW  *numberOfLBnodes];
+         dist.f[BS  ] = &distributionArray[TN  *numberOfLBnodes];
+         dist.f[TN  ] = &distributionArray[BS  *numberOfLBnodes];
+         dist.f[TS  ] = &distributionArray[BN  *numberOfLBnodes];
+         dist.f[BN  ] = &distributionArray[TS  *numberOfLBnodes];
+         dist.f[REST] = &distributionArray[REST*numberOfLBnodes];
+         dist.f[TNE ] = &distributionArray[BSW *numberOfLBnodes];
+         dist.f[TSW ] = &distributionArray[BNE *numberOfLBnodes];
+         dist.f[TSE ] = &distributionArray[BNW *numberOfLBnodes];
+         dist.f[TNW ] = &distributionArray[BSE *numberOfLBnodes];
+         dist.f[BNE ] = &distributionArray[TSW *numberOfLBnodes];
+         dist.f[BSW ] = &distributionArray[TNE *numberOfLBnodes];
+         dist.f[BSE ] = &distributionArray[TNW *numberOfLBnodes];
+         dist.f[BNW ] = &distributionArray[TSE *numberOfLBnodes];
+    }
+}
+
+__inline__ __device__ void getPointersToSubgridDistances(SubgridDistances27& subgridD, real* subgridDistances, const unsigned int numberOfSubgridIndices)
+{
+    subgridD.q[E   ] = &subgridDistances[E    *numberOfSubgridIndices];
+    subgridD.q[W   ] = &subgridDistances[W    *numberOfSubgridIndices];
+    subgridD.q[N   ] = &subgridDistances[N    *numberOfSubgridIndices];
+    subgridD.q[S   ] = &subgridDistances[S    *numberOfSubgridIndices];
+    subgridD.q[T   ] = &subgridDistances[T    *numberOfSubgridIndices];
+    subgridD.q[B   ] = &subgridDistances[B    *numberOfSubgridIndices];
+    subgridD.q[NE  ] = &subgridDistances[NE   *numberOfSubgridIndices];
+    subgridD.q[SW  ] = &subgridDistances[SW   *numberOfSubgridIndices];
+    subgridD.q[SE  ] = &subgridDistances[SE   *numberOfSubgridIndices];
+    subgridD.q[NW  ] = &subgridDistances[NW   *numberOfSubgridIndices];
+    subgridD.q[TE  ] = &subgridDistances[TE   *numberOfSubgridIndices];
+    subgridD.q[BW  ] = &subgridDistances[BW   *numberOfSubgridIndices];
+    subgridD.q[BE  ] = &subgridDistances[BE   *numberOfSubgridIndices];
+    subgridD.q[TW  ] = &subgridDistances[TW   *numberOfSubgridIndices];
+    subgridD.q[TN  ] = &subgridDistances[TN   *numberOfSubgridIndices];
+    subgridD.q[BS  ] = &subgridDistances[BS   *numberOfSubgridIndices];
+    subgridD.q[BN  ] = &subgridDistances[BN   *numberOfSubgridIndices];
+    subgridD.q[TS  ] = &subgridDistances[TS   *numberOfSubgridIndices];
+    subgridD.q[REST] = &subgridDistances[REST *numberOfSubgridIndices];
+    subgridD.q[TNE ] = &subgridDistances[TNE  *numberOfSubgridIndices];
+    subgridD.q[TSW ] = &subgridDistances[TSW  *numberOfSubgridIndices];
+    subgridD.q[TSE ] = &subgridDistances[TSE  *numberOfSubgridIndices];
+    subgridD.q[TNW ] = &subgridDistances[TNW  *numberOfSubgridIndices];
+    subgridD.q[BNE ] = &subgridDistances[BNE  *numberOfSubgridIndices];
+    subgridD.q[BSW ] = &subgridDistances[BSW  *numberOfSubgridIndices];
+    subgridD.q[BSE ] = &subgridDistances[BSE  *numberOfSubgridIndices];
+    subgridD.q[BNW ] = &subgridDistances[BNW  *numberOfSubgridIndices];
+}
+
+__inline__ __device__ real getEquilibriumForBC(const real& drho, const real& velocity, const real& cu_sq, const real weight)
+{
+    return weight * (drho + c9o2 * velocity * velocity * (c1o1 + drho) - cu_sq);
+}
+
+__inline__ __device__ real getInterpolatedDistributionForVeloBC(const real& q, const real& f, const real& fInverse, const real& feq, 
+                                                                const real& omega, const real& velocity, const real weight)
+{
+
+    return (c1o1-q) / (c1o1+q) * (f - fInverse + (f + fInverse - c2o1 * feq * omega) / (c1o1 - omega)) * c1o2 
+           + (q * (f + fInverse) - c6o1 * weight * velocity) / (c1o1 + q);
+}
+
+__inline__ __device__ real getInterpolatedDistributionForNoSlipBC(const real& q, const real& f, const real& fInverse, const real& feq, 
+                                                                  const real& omega)
+{
+
+    return (c1o1-q) / (c1o1+q) * (f - fInverse + (f + fInverse - c2o1 * feq * omega) / (c1o1 - omega)) * c1o2 
+           + (q * (f + fInverse)) / (c1o1 + q);
+}
+
+
+__inline__ __device__ real getInterpolatedDistributionForVeloWithPressureBC(const real& q, const real& f, const real& fInverse, const real& feq, 
+                                                                            const real& omega, const real& drho, const real& velocity, const real weight)
+{
+
+    return (c1o1-q) / (c1o1+q) * (f - fInverse + (f + fInverse - c2o1 * feq * omega) / (c1o1 - omega)) * c1o2 
+           + (q * (f + fInverse) - c6o1 * weight * velocity) / (c1o1 + q) - weight * drho;
+}
+
+
+
+#endif
diff --git a/src/gpu/VirtualFluids_GPU/GPU/LBMKernel.cu b/src/gpu/VirtualFluids_GPU/GPU/LBMKernel.cu
index 784793b54018f322fc48cef5660a618fad1ecd99..e7e51f8da746f1529bda04f511dfcc1d78dcb6f7 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/LBMKernel.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/LBMKernel.cu
@@ -34,6 +34,9 @@
 
 #include "LBM/LB.h"
 #include "GPU/GPU_Kernels.cuh"
+#include "cuda/CudaGrid.h"
+#include "Parameter/Parameter.h"
+
 //////////////////////////////////////////////////////////////////////////
 extern "C" void CumulantK17LBMDeviceKernel(
 	uint numberOfThreads,
@@ -202,48 +205,124 @@ extern "C" void CalcMacADCompSP27(
 	getLastCudaError("LBCalcMacADCompSP27 execution failed");
 }
 //////////////////////////////////////////////////////////////////////////
-extern "C" void QVelDevicePlainBB27(
-	unsigned int numberOfThreads,
-	real* velocityX,
-	real* velocityY,
-	real* velocityZ,
-	real* distributions,
-	int* k_Q,
-	real* QQ,
-	uint sizeQ,
-	int kQ,
-	uint* neighborX,
-	uint* neighborY,
-	uint* neighborZ,
-	uint size_Mat,
-	bool isEvenTimestep)
+extern "C" void QVelDevPlainBB27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
 {
-	int Grid = (kQ / numberOfThreads) + 1;
-	dim3 gridQ(Grid, 1, 1);
-	dim3 threads(numberOfThreads, 1, 1);
+   dim3 grid = vf::cuda::getCudaGrid( parameterDevice->numberofthreads, boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
-	QVelDevPlainBB27 <<< gridQ, threads >>> (
-		velocityX,
-		velocityY,
-		velocityZ,
-		distributions,
-		k_Q,
-		QQ,
-		sizeQ,
-		kQ,
-		neighborX,
-		neighborY,
-		neighborZ,
-		size_Mat,
-		isEvenTimestep);
-	getLastCudaError("QVelDevicePlainBB27 execution failed");
+   QVelDevicePlainBB27<<< grid, threads >>> (
+         boundaryCondition->Vx,
+         boundaryCondition->Vy,
+         boundaryCondition->Vz,
+         parameterDevice->distributions.f[0],
+         boundaryCondition->k,
+         boundaryCondition->q27[0],
+         boundaryCondition->numberOfBCnodes,
+         parameterDevice->neighborX,
+         parameterDevice->neighborY,
+         parameterDevice->neighborZ,
+         parameterDevice->numberOfNodes,
+         parameterDevice->isEvenTimestep);
+   getLastCudaError("QVelDevicePlainBB27 execution failed");
 }
+//////////////////////////////////////////////////////////////////////////
+extern "C" void QVelDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
+{
+   dim3 grid = vf::cuda::getCudaGrid(parameterDevice->numberofthreads,  boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
+   QVelDeviceComp27<<< grid, threads >>> (
+            boundaryCondition->Vx,
+            boundaryCondition->Vy,
+            boundaryCondition->Vz,
+            parameterDevice->distributions.f[0],
+            boundaryCondition->k,
+            boundaryCondition->q27[0],
+            boundaryCondition->numberOfBCnodes,
+            parameterDevice->omega,
+            parameterDevice->neighborX,
+            parameterDevice->neighborY,
+            parameterDevice->neighborZ,
+            parameterDevice->numberOfNodes,
+            parameterDevice->isEvenTimestep);
+   getLastCudaError("QVelDeviceComp27 execution failed");
+}
+//////////////////////////////////////////////////////////////////////////
+extern "C" void BBDev27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
+{
+   dim3 grid = vf::cuda::getCudaGrid( parameterDevice->numberofthreads,  boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
+   BBDevice27<<< grid, threads >>> (
+         parameterDevice->distributions.f[0],
+         boundaryCondition->k,
+         boundaryCondition->q27[0],
+         boundaryCondition->numberOfBCnodes,
+         parameterDevice->neighborX,
+         parameterDevice->neighborY,
+         parameterDevice->neighborZ,
+         parameterDevice->numberOfNodes,
+         parameterDevice->isEvenTimestep);
+   getLastCudaError("BBDevice27 execution failed");
+}
+//////////////////////////////////////////////////////////////////////////
+extern "C" void QDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
+{
+   dim3 grid = vf::cuda::getCudaGrid( parameterDevice->numberofthreads,  boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
+      QDeviceComp27<<< grid, threads >>> (
+           parameterDevice->distributions.f[0],
+           boundaryCondition->k,
+           boundaryCondition->q27[0],
+           boundaryCondition->numberOfBCnodes,
+           parameterDevice->omega,
+           parameterDevice->neighborX,
+           parameterDevice->neighborY,
+           parameterDevice->neighborZ,
+           parameterDevice->numberOfNodes,
+           parameterDevice->isEvenTimestep);
+      getLastCudaError("QDeviceComp27 execution failed");
+}
+//////////////////////////////////////////////////////////////////////////
+extern "C" void QSlipDevComp27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
+{
+   dim3 grid = vf::cuda::getCudaGrid( parameterDevice->numberofthreads, boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
+   QSlipDeviceComp27<<< grid, threads >>> (
+         parameterDevice->distributions.f[0],
+         boundaryCondition->k,
+         boundaryCondition->q27[0],
+         boundaryCondition->numberOfBCnodes,
+         parameterDevice->omega,
+         parameterDevice->neighborX,
+         parameterDevice->neighborY,
+         parameterDevice->neighborZ,
+         parameterDevice->numberOfNodes,
+         parameterDevice->isEvenTimestep);
+   getLastCudaError("QSlipDeviceComp27 execution failed");
+}
+//////////////////////////////////////////////////////////////////////////
+extern "C" void QPressDevNEQ27(ParameterStruct* parameterDevice, QforBoundaryConditions* boundaryCondition)
+{
+   dim3 grid = vf::cuda::getCudaGrid( parameterDevice->numberofthreads,  boundaryCondition->numberOfBCnodes);
+   dim3 threads(parameterDevice->numberofthreads, 1, 1 );
 
-
+   QPressDeviceNEQ27<<< grid, threads >>> (
+        boundaryCondition->RhoBC,
+        parameterDevice->distributions.f[0],
+        boundaryCondition->k,
+        boundaryCondition->kN,
+        boundaryCondition->numberOfBCnodes,
+        parameterDevice->omega,
+        parameterDevice->neighborX,
+        parameterDevice->neighborY,
+        parameterDevice->neighborZ,
+        parameterDevice->numberOfNodes,
+        parameterDevice->isEvenTimestep);
+   getLastCudaError("QPressDevNEQ27 execution failed");
+}
 
 
 
@@ -254,7 +333,7 @@ extern "C" void QVelDevicePlainBB27(
 //////////////////////////////////////////////////////////////////////////
 extern "C" void FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
 	uint numberOfThreads,
-	real omegaD,
+	real omegaDiffusivity,
 	uint* typeOfGridNode,
 	uint* neighborX,
 	uint* neighborY,
@@ -270,7 +349,7 @@ extern "C" void FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
 	dim3 threads(numberOfThreads, 1, 1);
 
 	Factorized_Central_Moments_Advection_Diffusion_Device_Kernel <<< grid, threads >>> (
-		omegaD,
+		omegaDiffusivity,
 		typeOfGridNode,
 		neighborX,
 		neighborY,
@@ -283,7 +362,7 @@ extern "C" void FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
 	getLastCudaError("Factorized_Central_Moments_Advection_Diffusion_Device_Kernel execution failed");
 }
 //////////////////////////////////////////////////////////////////////////
-extern "C" void InitADdevice(
+extern "C" void InitADDev27(
 	uint numberOfThreads,
 	uint* neighborX,
 	uint* neighborY,
@@ -345,15 +424,15 @@ extern "C" void CalcConcentration27(
 //////////////////////////////////////////////////////////////////////////
 extern "C" void ADSlipVelDevComp(
 	uint numberOfThreads,
-	real * NormalX,
-	real * NormalY,
-	real * NormalZ,
+	real * normalX,
+	real * normalY,
+	real * normalZ,
 	real * distributions,
 	real * distributionsAD,
 	int* QindexArray,
 	real * Qarrays,
 	uint numberOfQs,
-	real omegaD,
+	real omegaDiffusivity,
 	uint * neighborX,
 	uint * neighborY,
 	uint * neighborZ,
@@ -365,15 +444,15 @@ extern "C" void ADSlipVelDevComp(
 	dim3 threads(numberOfThreads, 1, 1);
 
 	AD_SlipVelDeviceComp << < gridQ, threads >> > (
-		NormalX,
-		NormalY,
-		NormalZ,
+		normalX,
+		normalY,
+		normalZ,
 		distributions,
 		distributionsAD,
 		QindexArray,
 		Qarrays,
 		numberOfQs,
-		omegaD,
+		omegaDiffusivity,
 		neighborX,
 		neighborY,
 		neighborZ,
diff --git a/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu b/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu
deleted file mode 100644
index 8bc893a1276d16046a8b673ec1ba674fcaf014dd..0000000000000000000000000000000000000000
--- a/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu
+++ /dev/null
@@ -1,340 +0,0 @@
-//=======================================================================================
-// ____          ____    __    ______     __________   __      __       __        __
-// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
-//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
-//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
-//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
-//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
-//      \    \  |    |   ________________________________________________________________
-//       \    \ |    |  |  ______________________________________________________________|
-//        \    \|    |  |  |         __          __     __     __     ______      _______
-//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
-//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
-//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
-//
-//  This file is part of VirtualFluids. VirtualFluids is free software: you can
-//  redistribute it and/or modify it under the terms of the GNU General Public
-//  License as published by the Free Software Foundation, either version 3 of
-//  the License, or (at your option) any later version.
-//
-//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
-//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-//  for more details.
-//
-//  You should have received a copy of the GNU General Public License along
-//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file VelocityBCs27.cu
-//! \ingroup GPU
-//! \author Martin Schoenherr
-//=======================================================================================
-/* Device code */
-#include "LBM/LB.h"
-#include "LBM/D3Q27.h"
-#include <lbm/constants/NumericConstants.h>
-
-using namespace vf::lbm::constant;
-//////////////////////////////////////////////////////////////////////////////
-extern "C" __global__ void QVelDevPlainBB27(
-	real* vx,
-	real* vy,
-	real* vz,
-	real* distributions,
-	int* k_Q,
-	real* QQ,
-	uint sizeQ,
-	int kQ,
-	uint* neighborX,
-	uint* neighborY,
-	uint* neighborZ,
-	uint size_Mat,
-	bool isEvenTimestep)
-{
-	//////////////////////////////////////////////////////////////////////////
-	//! The velocity boundary condition is executed in the following steps
-	//!
-	////////////////////////////////////////////////////////////////////////////////
-	//! - Get node index coordinates from thredIdx, blockIdx, blockDim and gridDim.
-	//!
-	const unsigned  x = threadIdx.x;  // Globaler x-Index
-   const unsigned  y = blockIdx.x;   // Globaler y-Index
-   const unsigned  z = blockIdx.y;   // Globaler z-Index
-
-   const unsigned nx = blockDim.x;
-   const unsigned ny = gridDim.x;
-
-   const unsigned k = nx*(ny*z + y) + x;
-
-   //////////////////////////////////////////////////////////////////////////
-   // run for all indices in size of boundary condition (kQ)
-   if(k<kQ)
-   {
-	   //////////////////////////////////////////////////////////////////////////
-	   //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref
-	   //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
-	   //!
-	   Distributions27 dist;
-	   if (isEvenTimestep)
-	   {
-		  dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-		  dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-		  dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-		  dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-		  dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-		  dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-		  dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-		  dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-		  dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-		  dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-		  dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-		  dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-		  dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-		  dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-		  dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-		  dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-		  dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-		  dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-		  dist.f[dirREST] = &distributions[dirREST*size_Mat];
-		  dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-		  dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-		  dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-		  dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-		  dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-		  dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-		  dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-		  dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
-	   }
-	   else
-	   {
-		  dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-		  dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-		  dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-		  dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-		  dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-		  dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-		  dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-		  dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-		  dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-		  dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-		  dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-		  dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-		  dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-		  dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-		  dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-		  dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-		  dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-		  dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-		  dist.f[dirREST] = &distributions[dirREST*size_Mat];
-		  dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-		  dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-		  dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
-		  dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-		  dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-		  dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-		  dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-		  dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-	   }
-
-
-	  ////////////////////////////////////////////////////////////////////////////////
-	  //! - Set local velocities
-	  //!
-	  real VeloX = vx[k];
-	  real VeloY = vy[k];
-	  real VeloZ = vz[k];
-      ////////////////////////////////////////////////////////////////////////////////
-	  //! - Set local subgrid distances (q's)
-	  //!
-      real   *q_dirE,   *q_dirW,   *q_dirN,   *q_dirS,   *q_dirT,   *q_dirB,
-			 *q_dirNE,  *q_dirSW,  *q_dirSE,  *q_dirNW,  *q_dirTE,  *q_dirBW,
-			 *q_dirBE,  *q_dirTW,  *q_dirTN,  *q_dirBS,  *q_dirBN,  *q_dirTS,
-			 *q_dirTNE, *q_dirTSW, *q_dirTSE, *q_dirTNW, *q_dirBNE, *q_dirBSW,
-			 *q_dirBSE, *q_dirBNW;
-      q_dirE   = &QQ[dirE   *sizeQ];
-      q_dirW   = &QQ[dirW   *sizeQ];
-      q_dirN   = &QQ[dirN   *sizeQ];
-      q_dirS   = &QQ[dirS   *sizeQ];
-      q_dirT   = &QQ[dirT   *sizeQ];
-      q_dirB   = &QQ[dirB   *sizeQ];
-      q_dirNE  = &QQ[dirNE  *sizeQ];
-      q_dirSW  = &QQ[dirSW  *sizeQ];
-      q_dirSE  = &QQ[dirSE  *sizeQ];
-      q_dirNW  = &QQ[dirNW  *sizeQ];
-      q_dirTE  = &QQ[dirTE  *sizeQ];
-      q_dirBW  = &QQ[dirBW  *sizeQ];
-      q_dirBE  = &QQ[dirBE  *sizeQ];
-      q_dirTW  = &QQ[dirTW  *sizeQ];
-      q_dirTN  = &QQ[dirTN  *sizeQ];
-      q_dirBS  = &QQ[dirBS  *sizeQ];
-      q_dirBN  = &QQ[dirBN  *sizeQ];
-      q_dirTS  = &QQ[dirTS  *sizeQ];
-      q_dirTNE = &QQ[dirTNE *sizeQ];
-      q_dirTSW = &QQ[dirTSW *sizeQ];
-      q_dirTSE = &QQ[dirTSE *sizeQ];
-      q_dirTNW = &QQ[dirTNW *sizeQ];
-      q_dirBNE = &QQ[dirBNE *sizeQ];
-      q_dirBSW = &QQ[dirBSW *sizeQ];
-      q_dirBSE = &QQ[dirBSE *sizeQ];
-      q_dirBNW = &QQ[dirBNW *sizeQ];
-      ////////////////////////////////////////////////////////////////////////////////
-	  //! - Set neighbor indices (necessary for indirect addressing)
-	  //!
-	  uint KQK = k_Q[k];
-      uint ke   = KQK;
-      uint kw   = neighborX[KQK];
-      uint kn   = KQK;
-      uint ks   = neighborY[KQK];
-      uint kt   = KQK;
-      uint kb   = neighborZ[KQK];
-      uint ksw  = neighborY[kw];
-      uint kne  = KQK;
-      uint kse  = ks;
-      uint knw  = kw;
-      uint kbw  = neighborZ[kw];
-      uint kte  = KQK;
-      uint kbe  = kb;
-      uint ktw  = kw;
-      uint kbs  = neighborZ[ks];
-      uint ktn  = KQK;
-      uint kbn  = kb;
-      uint kts  = ks;
-      uint ktse = ks;
-      uint kbnw = kbw;
-      uint ktnw = kw;
-      uint kbse = kbs;
-      uint ktsw = ksw;
-      uint kbne = kb;
-      uint ktne = KQK;
-      uint kbsw = neighborZ[ksw];
-      ////////////////////////////////////////////////////////////////////////////////
-
-      ////////////////////////////////////////////////////////////////////////////////
-	  //! - Set local distributions
-	  //!
-	  real f_W = (dist.f[dirE])[ke];
-      real f_E    = (dist.f[dirW   ])[kw   ];
-      real f_S    = (dist.f[dirN   ])[kn   ];
-      real f_N    = (dist.f[dirS   ])[ks   ];
-      real f_B    = (dist.f[dirT   ])[kt   ];
-      real f_T    = (dist.f[dirB   ])[kb   ];
-      real f_SW   = (dist.f[dirNE  ])[kne  ];
-      real f_NE   = (dist.f[dirSW  ])[ksw  ];
-      real f_NW   = (dist.f[dirSE  ])[kse  ];
-      real f_SE   = (dist.f[dirNW  ])[knw  ];
-      real f_BW   = (dist.f[dirTE  ])[kte  ];
-      real f_TE   = (dist.f[dirBW  ])[kbw  ];
-      real f_TW   = (dist.f[dirBE  ])[kbe  ];
-      real f_BE   = (dist.f[dirTW  ])[ktw  ];
-      real f_BS   = (dist.f[dirTN  ])[ktn  ];
-      real f_TN   = (dist.f[dirBS  ])[kbs  ];
-      real f_TS   = (dist.f[dirBN  ])[kbn  ];
-      real f_BN   = (dist.f[dirTS  ])[kts  ];
-      real f_BSW  = (dist.f[dirTNE ])[ktne ];
-      real f_BNE  = (dist.f[dirTSW ])[ktsw ];
-      real f_BNW  = (dist.f[dirTSE ])[ktse ];
-      real f_BSE  = (dist.f[dirTNW ])[ktnw ];
-      real f_TSW  = (dist.f[dirBNE ])[kbne ];
-      real f_TNE  = (dist.f[dirBSW ])[kbsw ];
-      real f_TNW  = (dist.f[dirBSE ])[kbse ];
-      real f_TSE  = (dist.f[dirBNW ])[kbnw ];
-	  ////////////////////////////////////////////////////////////////////////////////
-
-	  ////////////////////////////////////////////////////////////////////////////////
-	  //! - change the pointer to write the results in the correct array
-	  //!
-	  if (!isEvenTimestep)
-      {
-         dist.f[dirE   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirW   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirTSE *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirBNW *size_Mat];
-      }
-      else
-      {
-         dist.f[dirW   ] = &distributions[dirE   *size_Mat];
-         dist.f[dirE   ] = &distributions[dirW   *size_Mat];
-         dist.f[dirS   ] = &distributions[dirN   *size_Mat];
-         dist.f[dirN   ] = &distributions[dirS   *size_Mat];
-         dist.f[dirB   ] = &distributions[dirT   *size_Mat];
-         dist.f[dirT   ] = &distributions[dirB   *size_Mat];
-         dist.f[dirSW  ] = &distributions[dirNE  *size_Mat];
-         dist.f[dirNE  ] = &distributions[dirSW  *size_Mat];
-         dist.f[dirNW  ] = &distributions[dirSE  *size_Mat];
-         dist.f[dirSE  ] = &distributions[dirNW  *size_Mat];
-         dist.f[dirBW  ] = &distributions[dirTE  *size_Mat];
-         dist.f[dirTE  ] = &distributions[dirBW  *size_Mat];
-         dist.f[dirTW  ] = &distributions[dirBE  *size_Mat];
-         dist.f[dirBE  ] = &distributions[dirTW  *size_Mat];
-         dist.f[dirBS  ] = &distributions[dirTN  *size_Mat];
-         dist.f[dirTN  ] = &distributions[dirBS  *size_Mat];
-         dist.f[dirTS  ] = &distributions[dirBN  *size_Mat];
-         dist.f[dirBN  ] = &distributions[dirTS  *size_Mat];
-         dist.f[dirREST] = &distributions[dirREST*size_Mat];
-         dist.f[dirTNE ] = &distributions[dirBSW *size_Mat];
-         dist.f[dirTSW ] = &distributions[dirBNE *size_Mat];
-         dist.f[dirTSE ] = &distributions[dirBNW *size_Mat];
-         dist.f[dirTNW ] = &distributions[dirBSE *size_Mat];
-         dist.f[dirBNE ] = &distributions[dirTSW *size_Mat];
-         dist.f[dirBSW ] = &distributions[dirTNE *size_Mat];
-         dist.f[dirBSE ] = &distributions[dirTNW *size_Mat];
-         dist.f[dirBNW ] = &distributions[dirTSE *size_Mat];
-      }
-	  ////////////////////////////////////////////////////////////////////////////////
-	  //! - rewrite distributions if there is a sub-grid distance (q) in same direction
-	  real q;
-      q = q_dirE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirW  ])[kw  ]=f_E   + c4o9  * (-VeloX);
-      q = q_dirW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirE  ])[ke  ]=f_W   + c4o9  * ( VeloX);
-      q = q_dirN[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirS  ])[ks  ]=f_N   + c4o9  * (-VeloY);
-      q = q_dirS[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirN  ])[kn  ]=f_S   + c4o9  * ( VeloY);
-      q = q_dirT[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirB  ])[kb  ]=f_T   + c4o9  * (-VeloZ);
-      q = q_dirB[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirT  ])[kt  ]=f_B   + c4o9  * ( VeloZ);
-      q = q_dirNE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirSW ])[ksw ]=f_NE  + c1o9  * (-VeloX - VeloY);
-	  q = q_dirSW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirNE ])[kne ]=f_SW  + c1o9  * ( VeloX + VeloY);
-	  q = q_dirSE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirNW ])[knw ]=f_SE  + c1o9  * (-VeloX + VeloY);
-	  q = q_dirNW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirSE ])[kse ]=f_NW  + c1o9  * ( VeloX - VeloY);
-	  q = q_dirTE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBW ])[kbw ]=f_TE  + c1o9  * (-VeloX - VeloZ);
-	  q = q_dirBW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTE ])[kte ]=f_BW  + c1o9  * ( VeloX + VeloZ);
-	  q = q_dirBE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTW ])[ktw ]=f_BE  + c1o9  * (-VeloX + VeloZ);
-	  q = q_dirTW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBE ])[kbe ]=f_TW  + c1o9  * ( VeloX - VeloZ);
-	  q = q_dirTN[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBS ])[kbs ]=f_TN  + c1o9  * (-VeloY - VeloZ);
-	  q = q_dirBS[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTN ])[ktn ]=f_BS  + c1o9  * ( VeloY + VeloZ);
-	  q = q_dirBN[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTS ])[kts ]=f_BN  + c1o9  * (-VeloY + VeloZ);
-	  q = q_dirTS[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBN ])[kbn ]=f_TS  + c1o9  * ( VeloY - VeloZ);
-      q = q_dirTNE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBSW])[kbsw]=f_TNE + c1o36 * (-VeloX - VeloY - VeloZ);
-      q = q_dirBSW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTNE])[ktne]=f_BSW + c1o36 * ( VeloX + VeloY + VeloZ);
-      q = q_dirBNE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTSW])[ktsw]=f_BNE + c1o36 * (-VeloX - VeloY + VeloZ);
-      q = q_dirTSW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBNE])[kbne]=f_TSW + c1o36 * ( VeloX + VeloY - VeloZ);
-      q = q_dirTSE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBNW])[kbnw]=f_TSE + c1o36 * (-VeloX + VeloY - VeloZ);
-      q = q_dirBNW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTSE])[ktse]=f_BNW + c1o36 * ( VeloX - VeloY + VeloZ);
-      q = q_dirBSE[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirTNW])[ktnw]=f_BSE + c1o36 * (-VeloX + VeloY + VeloZ);
-      q = q_dirTNW[k];	if (q>=c0o1 && q<=c1o1)	(dist.f[dirBSE])[kbse]=f_TNW + c1o36 * ( VeloX - VeloY - VeloZ);
-   }
-}
-
-
-
diff --git a/src/gpu/VirtualFluids_GPU/Init/InitLattice.cpp b/src/gpu/VirtualFluids_GPU/Init/InitLattice.cpp
index 7475eece94255451208d2ad5dbca5397e5815f12..70288317d923f2ea786acf6350a7fb539a3b2457 100644
--- a/src/gpu/VirtualFluids_GPU/Init/InitLattice.cpp
+++ b/src/gpu/VirtualFluids_GPU/Init/InitLattice.cpp
@@ -33,10 +33,10 @@
 #include "Init/InitLattice.h"
 #include "Parameter/Parameter.h"
 #include "GPU/GPU_Interface.h"
-#include "AdvectionDiffusion/AdvectionDiffusion.h"
+#include "KernelManager/ADKernelManager.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-void initLattice(SPtr<Parameter> para)
+void initLattice(SPtr<Parameter> para, ADKernelManager* adKernelManager)
 {
 	//////////////////////////////////////////////////////////////////////////
 	para->getParD()->isEvenTimestep = true;
@@ -89,6 +89,5 @@ void initLattice(SPtr<Parameter> para)
 
 	//////////////////////////////////////////////////////////////////////////
     if (para->getIsADcalculationOn())
-        initAD(para);
-
+        adKernelManager->initAD();
 }
diff --git a/src/gpu/VirtualFluids_GPU/Init/InitLattice.h b/src/gpu/VirtualFluids_GPU/Init/InitLattice.h
index 4c51d2ee0a4f500aaa3dd4d49217fe603059e9d5..c7b1912315109dd9f3c3b652d3fdab27e0d5b614 100644
--- a/src/gpu/VirtualFluids_GPU/Init/InitLattice.h
+++ b/src/gpu/VirtualFluids_GPU/Init/InitLattice.h
@@ -37,9 +37,10 @@
 
 //! \brief Class forwarding for Parameter
 class Parameter;
+class ADKernelManager;
 
 //! \brief initialize the LBM lattice
 //! \param para instance of classParameter
-void initLattice(SPtr<Parameter> para);
+void initLattice(SPtr<Parameter> para, ADKernelManager* adKernelManager);
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.cpp
similarity index 88%
rename from src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.cpp
rename to src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.cpp
index f466cb5c0a21fdf7119cf7bc682d2b432a5e3a96..53c7707b6be07f5115f0585ad896402b453c4ddc 100644
--- a/src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.cpp
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.cpp
@@ -30,21 +30,21 @@
 //! \ingroup AdvectionDiffusion
 //! \author Martin Schoenherr
 //=======================================================================================
-#include "AdvectionDiffusion/AdvectionDiffusion.h"
+#include "KernelManager/ADKernelManager.h"
 #include "GPU/CudaMemoryManager.h"
 #include "GPU/GPU_Interface.h"
 #include "Parameter/Parameter.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-void initAD(SPtr<Parameter> para)
+void ADKernelManager::initAD()
 {
     //////////////////////////////////////////////////////////////////////////
     // calculation of omega for diffusivity
-    para->getParD()->omegaD = (real)2.0 / ((real)6.0 * para->getParD()->diffusivity + (real)1.0);
+    para->getParD()->omegaDiffusivity = (real)2.0 / ((real)6.0 * para->getParD()->diffusivity + (real)1.0);
     //////////////////////////////////////////////////////////////////////////
     para->getParD()->isEvenTimestep = true;
     //////////////////////////////////////////////////////////////////////////
-    InitADdevice(
+    InitADDev27(
         para->getParD()->numberofthreads, 
         para->getParD()->neighborX, 
         para->getParD()->neighborY,
@@ -60,7 +60,7 @@ void initAD(SPtr<Parameter> para)
     //////////////////////////////////////////////////////////////////////////
     para->getParD()->isEvenTimestep = false;
     //////////////////////////////////////////////////////////////////////////
-    InitADdevice(
+    InitADDev27(
         para->getParD()->numberofthreads, 
         para->getParD()->neighborX, 
         para->getParD()->neighborY,
@@ -87,7 +87,7 @@ void initAD(SPtr<Parameter> para)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void setInitialNodeValuesAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager)
+void ADKernelManager::setInitialNodeValuesAD(SPtr<CudaMemoryManager> cudaMemoryManager)
 {
     for (uint j = 1; j <= para->getParH()->numberOfNodes; j++) {
         const real coordX = para->getParH()->coordinateX[j];
@@ -110,11 +110,11 @@ void setInitialNodeValuesAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMe
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void calcAD(SPtr<Parameter> para)
+void ADKernelManager::runADcollisionKernel()
 {
     FactorizedCentralMomentsAdvectionDiffusionDeviceKernel(
         para->getParD()->numberofthreads,
-        para->getParD()->omegaD,
+        para->getParD()->omegaDiffusivity,
         para->getParD()->typeOfGridNode,
         para->getParD()->neighborX,
         para->getParD()->neighborY,
@@ -124,19 +124,21 @@ void calcAD(SPtr<Parameter> para)
         para->getParD()->numberOfNodes,
         para->getParD()->forcing,
         para->getParD()->isEvenTimestep);
+}
 
-    if (para->getParD()->numberOfSlipBCnodes > 1) {
+void ADKernelManager::runADslipBCKernel(){
+    if (para->getParD()->slipBC.numberOfBCnodes > 1) {
         ADSlipVelDevComp(
             para->getParD()->numberofthreads,
-            para->getParD()->slipBC.NormalX,
-            para->getParD()->slipBC.NormalY,
-            para->getParD()->slipBC.NormalZ,
+            para->getParD()->slipBC.normalX,
+            para->getParD()->slipBC.normalY,
+            para->getParD()->slipBC.normalZ,
             para->getParD()->distributions.f[0],
             para->getParD()->distributionsAD.f[0],
             para->getParD()->slipBC.k,
             para->getParD()->slipBC.q27[0],
-            para->getParD()->numberOfSlipBCnodes,
-            para->getParD()->omegaD,
+            para->getParD()->slipBC.numberOfBCnodes,
+            para->getParD()->omegaDiffusivity,
             para->getParD()->neighborX,
             para->getParD()->neighborY,
             para->getParD()->neighborZ,
@@ -145,8 +147,9 @@ void calcAD(SPtr<Parameter> para)
     }
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
-void printAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager)
+void ADKernelManager::printAD(SPtr<CudaMemoryManager> cudaMemoryManager)
 {
     CalcConcentration27(
         para->getParD()->numberofthreads,
@@ -161,3 +164,5 @@ void printAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager)
 
     cudaMemoryManager->cudaCopyConcentrationDeviceToHost();
 }
+
+ADKernelManager::ADKernelManager(SPtr<Parameter> parameter): para(parameter){}
diff --git a/src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.h b/src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.h
similarity index 63%
rename from src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.h
rename to src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.h
index 659b0a9b29fc157e47de8870fd37536718a1839e..d48b2ff0631efe52369712bfceb5168b115f762d 100644
--- a/src/gpu/VirtualFluids_GPU/AdvectionDiffusion/AdvectionDiffusion.h
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/ADKernelManager.h
@@ -33,29 +33,48 @@
 #ifndef ADVECTION_DIFFUSION_H
 #define ADVECTION_DIFFUSION_H
 
-#include "PointerDefinitions.h"
 #include "Core/DataTypes.h"
+#include "PointerDefinitions.h"
+#include "VirtualFluids_GPU_export.h"
 
 //! \brief Class forwarding for Parameter, DataWriter and CudaMemoryManager
 class Parameter;
 class CudaMemoryManager;
 
-//! \brief initialize the Advection Diffusion distributions
-//! \param para instance of class Parameter
-void initAD(SPtr<Parameter> para);
+//! \class ADKernelManager
+//! \brief manage the advection diffusion kernel calls
+class VIRTUALFLUIDS_GPU_EXPORT ADKernelManager
+{
+
+public:
+    //! Class constructor
+    //! \param parameter shared pointer to instance of class Parameter
+    ADKernelManager(SPtr<Parameter> parameter);
+    
+    //! \brief initialize the Advection Diffusion distributions
+    //! \param para instance of class Parameter
+    void initAD();
+
+    //! \brief set initial concentration values at all nodes
+    //! \param para instance of class Parameter
+    //! \param cudaManager instance of class CudaMemoryManager
+    void setInitialNodeValuesAD(SPtr<CudaMemoryManager> cudaMemoryManager);
+
+    //! \brief calculate the state of the next time step of the Advection Diffusion distributions
+    //! \param para instance of class Parameter
+    void runADcollisionKernel();
 
-//! \brief set initial concentration values at all nodes
-//! \param para instance of class Parameter
-//! \param cudaManager instance of class CudaMemoryManager
-void setInitialNodeValuesAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager);
+    //! \brief calls the device function of the slip boundary condition for advection diffusion
+    void runADslipBCKernel();
 
-//! \brief calculate the state of the next time step of the Advection Diffusion distributions
-//! \param para instance of class Parameter
-void calcAD(SPtr<Parameter> para);
+    //! \brief copy the concentration from device to host and writes VTK file with concentration
+    //! \param para instance of class Parameter
+    //! \param cudaManager instance of class CudaMemoryManager
+    void printAD(SPtr<CudaMemoryManager> cudaMemoryManager);
 
-//! \brief copy the concentration from device to host and writes VTK file with concentration
-//! \param para instance of class Parameter
-//! \param cudaManager instance of class CudaMemoryManager
-void printAD(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager);
+private:
+    //! \property para is a shared pointer to an object of Parameter
+    SPtr<Parameter> para;
+};
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..586e817e01b872b11dc00d956ffd9a97fabde25b
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp
@@ -0,0 +1,86 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBKernelManager.cpp
+//! \ingroup KernelManager
+//! \author Martin Schoenherr
+//=======================================================================================
+#include <cuda_runtime.h>
+#include <helper_cuda.h>
+#include <iostream>
+
+#include "BCKernelManager.h"
+#include "Parameter/Parameter.h"
+#include "GPU/GPU_Interface.h"
+#include "BoundaryConditions/BoundaryConditionFactory.h"
+
+BCKernelManager::BCKernelManager(SPtr<Parameter> parameter, BoundaryConditionFactory* bcFactory): para(parameter)
+{
+    this->velocityBoundaryConditionPost = bcFactory->getVelocityBoundaryConditionPost();
+    this->noSlipBoundaryConditionPost   = bcFactory->getNoSlipBoundaryConditionPost();
+    this->slipBoundaryConditionPost     = bcFactory->getSlipBoundaryConditionPost();
+    this->pressureBoundaryConditionPre  = bcFactory->getPressureBoundaryConditionPre();
+    this->geometryBoundaryConditionPost = bcFactory->getGeometryBoundaryConditionPost();
+}
+
+void BCKernelManager::runVelocityBCKernelPost(const int level) const
+{
+     if (para->getParD(level)->velocityBC.numberOfBCnodes > 0)
+     {
+        this->velocityBoundaryConditionPost(para->getParD(level).get(), &(para->getParD(level)->velocityBC));
+     }
+}
+
+void BCKernelManager::runGeoBCKernelPost(const int level) const
+{
+    if (para->getParD(level)->geometryBC.numberOfBCnodes > 0)
+    {
+        this->geometryBoundaryConditionPost(para->getParD(level).get(), &(para->getParD(level)->geometryBC));
+    }
+}
+
+void BCKernelManager::runPressureBCKernelPre(const int level) const{
+    if (para->getParD(level)->pressureBC.numberOfBCnodes > 0)
+    {
+        this->pressureBoundaryConditionPre(para->getParD(level).get(), &(para->getParD(level)->pressureBC));
+    }
+}
+
+void BCKernelManager::runSlipBCKernelPost(const int level) const{
+    if (para->getParD(level)->slipBC.numberOfBCnodes > 0)
+    {
+        this->slipBoundaryConditionPost(para->getParD(level).get(), &(para->getParD(level)->slipBC));
+    }
+}
+
+void BCKernelManager::runNoSlipBCKernelPost(const int level) const{
+    if (para->getParD(level)->noSlipBC.numberOfBCnodes > 0)
+    {
+        this->noSlipBoundaryConditionPost(para->getParD(level).get(), &(para->getParD(level)->noSlipBC));
+    }
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.h b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..a519d40cf06b34d4d7ee8f477f6dccd8e77bb049
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.h
@@ -0,0 +1,85 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCKernelManager.h
+//! \ingroup KernelManager
+//! \author Martin Schoenherr
+//=======================================================================================
+#ifndef BCKernelManager_H
+#define BCKernelManager_H
+
+#include <functional>
+#include <memory>
+
+#include "Parameter/Parameter.h"
+#include "PointerDefinitions.h"
+#include "VirtualFluids_GPU_export.h"
+#include "LBM/LB.h"
+
+class CudaMemoryManager;
+class BoundaryConditionFactory;
+class Parameter;
+struct ParameterStruct;
+
+using boundaryCondition = std::function<void(ParameterStruct *, QforBoundaryConditions *)>;
+using boundaryConditionPara = std::function<void(Parameter *, QforBoundaryConditions *, const int level)>;
+
+//! \class BCKernelManager
+//! \brief manage the cuda kernel calls to boundary conditions
+class VIRTUALFLUIDS_GPU_EXPORT BCKernelManager
+{
+public:
+    //! Class constructor
+    //! \param parameter shared pointer to instance of class Parameter
+    BCKernelManager(SPtr<Parameter> parameter, BoundaryConditionFactory *bcFactory);
+
+    //! \brief calls the device function of the velocity boundary condition (post-collision)
+    void runVelocityBCKernelPost(const int level) const;
+
+    //! \brief calls the device function of the geometry boundary condition (post-collision)
+    void runGeoBCKernelPost(const int level) const;
+
+    //! \brief calls the device function of the slip boundary condition (post-collision)
+    void runSlipBCKernelPost(const int level) const;
+
+    //! \brief calls the device function of the no-slip boundary condition (post-collision)
+    void runNoSlipBCKernelPost(const int level) const;
+
+    //! \brief calls the device function of the pressure boundary condition (pre-collision)
+    void runPressureBCKernelPre(const int level) const;
+
+private:
+    SPtr<Parameter> para;
+
+    boundaryCondition velocityBoundaryConditionPost;
+    boundaryCondition noSlipBoundaryConditionPost;
+    boundaryCondition slipBoundaryConditionPost;
+    boundaryCondition pressureBoundaryConditionPre;
+    boundaryCondition geometryBoundaryConditionPost;
+};
+#endif
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d94c73f5367aca4f9300a753a115c5717fcd991
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.cpp
@@ -0,0 +1,110 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBKernelManager.cpp
+//! \ingroup GPU
+//! \author Martin Schoenherr
+//=======================================================================================
+#include <cuda_runtime.h>
+#include <helper_cuda.h>
+#include "LBKernelManager.h"
+#include "GPU/GPU_Interface.h"
+#include <Parameter/Parameter.h>
+
+
+void LBKernelManager::runLBMKernel(SPtr<Parameter> para)
+{
+    if (para->getIsADcalculationOn()) {
+        CumulantK17LBMDeviceKernelAD(
+            para->getParD()->numberofthreads,
+            para->getParD()->omega,
+            para->getParD()->typeOfGridNode,
+            para->getParD()->neighborX,
+            para->getParD()->neighborY,
+            para->getParD()->neighborZ,
+            para->getParD()->distributions.f[0],
+            para->getParD()->distributionsAD.f[0],
+            para->getParD()->numberOfNodes,
+            para->getParD()->forcing,
+            para->getParD()->isEvenTimestep);
+    } else {
+        CumulantK17LBMDeviceKernel(
+            para->getParD()->numberofthreads,
+            para->getParD()->omega,
+            para->getParD()->typeOfGridNode,
+            para->getParD()->neighborX,
+            para->getParD()->neighborY,
+            para->getParD()->neighborZ,
+            para->getParD()->distributions.f[0],
+            para->getParD()->numberOfNodes,
+            para->getParD()->forcing,
+            para->getParD()->isEvenTimestep);
+    }
+}
+
+void LBKernelManager::calculateMacroscopicValues(SPtr<Parameter> para)
+{
+    if (para->getIsADcalculationOn()) {
+        CalcMacADCompSP27(
+            para->getParD()->velocityX,
+            para->getParD()->velocityY,
+            para->getParD()->velocityZ,
+            para->getParD()->rho,
+            para->getParD()->pressure,
+            para->getParD()->typeOfGridNode,
+            para->getParD()->neighborX,
+            para->getParD()->neighborY,
+            para->getParD()->neighborZ,
+            para->getParD()->numberOfNodes,
+            para->getParD()->numberofthreads,
+            para->getParD()->distributions.f[0],
+            para->getParD()->distributionsAD.f[0],
+            para->getParD()->forcing,
+            para->getParD()->isEvenTimestep);
+    } else {
+        CalcMacCompSP27(
+            para->getParD()->velocityX,
+            para->getParD()->velocityY,
+            para->getParD()->velocityZ,
+            para->getParD()->rho,
+            para->getParD()->pressure,
+            para->getParD()->typeOfGridNode,
+            para->getParD()->neighborX,
+            para->getParD()->neighborY,
+            para->getParD()->neighborZ,
+            para->getParD()->numberOfNodes,
+            para->getParD()->numberofthreads,
+            para->getParD()->distributions.f[0],
+            para->getParD()->isEvenTimestep);
+    }
+}
+
+LBKernelManager::LBKernelManager(SPtr<Parameter> parameter): parameter(parameter)
+{
+}
+
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.h b/src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.h
similarity index 67%
rename from src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.h
rename to src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.h
index 622bdf135b08ec74b3b45936312ab32e6ac603e6..d023457fe79bec456ce9c53e402bca9c06406df2 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaKernelManager.h
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/LBKernelManager.h
@@ -26,12 +26,12 @@
 //  You should have received a copy of the GNU General Public License along
 //  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
-//! \file CudaKernelManager.h
+//! \file LBKernelManager.h
 //! \ingroup GPU
 //! \author Martin Schoenherr
 //=======================================================================================
-#ifndef CudaKernelManager_H
-#define CudaKernelManager_H
+#ifndef LBKernelManager_H
+#define LBKernelManager_H
 
 #include <memory>
 #include "PointerDefinitions.h"
@@ -40,38 +40,25 @@
 //! \brief Class forwarding for Parameter
 class Parameter;
 
-//! \class CudaKernelManager
+//! \class LBKernelManager
 //! \brief manage the cuda kernel calls
-class VIRTUALFLUIDS_GPU_EXPORT CudaKernelManager
+class VIRTUALFLUIDS_GPU_EXPORT LBKernelManager
 {
 public:
-	//! \brief makes an object of CudaKernelManager
-	//! \param para shared pointer to instance of class Parameter
-    static SPtr<CudaKernelManager> make(std::shared_ptr<Parameter> parameter);
-    
-	//! \brief calls the device function of the lattice Boltzmann kernel
-	void runLBMKernel(SPtr<Parameter> para);
+    //! Class constructor
+    //! \param parameter shared pointer to instance of class Parameter
+    LBKernelManager(SPtr<Parameter> parameter);
 
-	//! \brief calls the device function of the velocity boundary condition
-    void runVelocityBCKernel(SPtr<Parameter> para);
+    //! \brief calls the device function of the lattice Boltzmann kernel
+    void runLBMKernel(SPtr<Parameter> para);
 
-	//! \brief calls the device function of the geometry boundary condition
-	void runGeoBCKernel(SPtr<Parameter> para);
-
-    //! \brief calls the device function that calculates the macroscopic values
+    //! \brief calls the device function to calculate the macroscopic values
     void calculateMacroscopicValues(SPtr<Parameter> para);
 
-
 private:
-	//! Class constructor
-	//! \param parameter shared pointer to instance of class Parameter
-	CudaKernelManager(SPtr<Parameter> parameter);
-	//! Class copy constructor
-	//! \param CudaKernelManager is a reference to CudaKernelManager object
-	CudaKernelManager(const CudaKernelManager&);
 
-	//! \property para is a shared pointer to an object of Parameter
-	SPtr<Parameter> parameter;
+    //! \property para is a shared pointer to an object of Parameter
+    SPtr<Parameter> parameter;
 
 };
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/LBM/D3Q27.h b/src/gpu/VirtualFluids_GPU/LBM/D3Q27.h
deleted file mode 100644
index ac0f4b2ae22698243dd3c03cfa2761b16a365994..0000000000000000000000000000000000000000
--- a/src/gpu/VirtualFluids_GPU/LBM/D3Q27.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//=======================================================================================
-// ____          ____    __    ______     __________   __      __       __        __         
-// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
-//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
-//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
-//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
-//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
-//      \    \  |    |   ________________________________________________________________    
-//       \    \ |    |  |  ______________________________________________________________|   
-//        \    \|    |  |  |         __          __     __     __     ______      _______    
-//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
-//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
-//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
-//
-//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
-//  redistribute it and/or modify it under the terms of the GNU General Public
-//  License as published by the Free Software Foundation, either version 3 of 
-//  the License, or (at your option) any later version.
-//  
-//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
-//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
-//  for more details.
-//  
-//  You should have received a copy of the GNU General Public License along
-//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file D3Q27.h
-//! \ingroup LBM
-//! \author Martin Schoenherr
-//=======================================================================================
-#ifndef _LB_D3Q27_H_
-#define _LB_D3Q27_H_
-
-//! \brief definitions of the 27 speeds (D3Q27)
-#define dirE    0
-#define dirW    1
-#define dirN    2
-#define dirS    3
-#define dirT    4
-#define dirB    5
-#define dirNE   6
-#define dirSW   7
-#define dirSE   8
-#define dirNW   9
-#define dirTE   10
-#define dirBW   11
-#define dirBE   12
-#define dirTW   13
-#define dirTN   14
-#define dirBS   15
-#define dirBN   16
-#define dirTS   17
-#define dirREST 18
-
-#define dirTNE  19
-#define dirBNE  20
-#define dirTSE  21
-#define dirBSE  22
-
-#define dirTNW  23
-#define dirBNW  24
-#define dirTSW  25
-#define dirBSW  26
-
-//! \brief definitions of start and end value (useful for loops)
-#define dirSTART  0
-#define dirEND   26
-
-#endif
-
-
diff --git a/src/gpu/VirtualFluids_GPU/LBM/LB.h b/src/gpu/VirtualFluids_GPU/LBM/LB.h
index 133ad8d672194b0c44382612d46e85c518c6467c..028ccb5d25a62ed97fb6eb6fa363e2511f671011 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/LB.h
+++ b/src/gpu/VirtualFluids_GPU/LBM/LB.h
@@ -50,12 +50,21 @@ typedef struct Distri27{
 
 //////////////////////////////////////////////////////////////////////////
 //! \struct to manage sub-grid-distances (q) for second order Boundary Conditions (BCs)
+typedef struct SubgridDist27{
+   real* q[27];
+} SubgridDistances27;
+
+
+//////////////////////////////////////////////////////////////////////////
+//! \struct to manage Boundary Conditions (BCs)
 typedef struct QforBC{
    int* k;
+   int* kN;
    real* q27[27];
-   int kArray;
+   unsigned int numberOfBCnodes = 0;
    real *Vx, *Vy, *Vz;
-   real *NormalX, *NormalY, *NormalZ;
+   real *RhoBC;
+   real *normalX, *normalY, *normalZ;
 } QforBoundaryConditions;
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
index 95d3f15dff5d3a31240c965a36d243096ba1a2ef..77a4eec971a8f9cca6bfd182443986cb47f5cf88 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
+++ b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
@@ -31,9 +31,10 @@
 //! \author Martin Schoenherr
 //=======================================================================================
 #include "Simulation.h"
-#include "AdvectionDiffusion/AdvectionDiffusion.h"
 #include "DataStructureInitializer/GridProvider.h"
-#include "GPU/CudaKernelManager.h"
+#include "KernelManager/LBKernelManager.h"
+#include "KernelManager/ADKernelManager.h"
+#include "KernelManager/BCKernelManager.h"
 #include "GPU/CudaMemoryManager.h"
 #include "GPU/devCheck.h"
 #include "Init/InitLattice.h"
@@ -42,20 +43,16 @@
 #include "Parameter/Parameter.h"
 
 #include "Core/Timer/Timer.h"
+#include "PointerDefinitions.h"
+#include "BoundaryConditions/BoundaryConditionFactory.h"
 
 #include <cuda_runtime.h>
 #include <helper_cuda.h>
-
 #include <memory>
-#include <stdio.h>
 //////////////////////////////////////////////////////////////////////////
 
-Simulation::Simulation() {}
-
-Simulation::~Simulation() {}
-
 void Simulation::init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, SPtr<DataWriter> dataWriter,
-                      SPtr<CudaMemoryManager> cudaMemoryManager)
+                      SPtr<CudaMemoryManager> cudaMemoryManager, BoundaryConditionFactory *bcFactory)
 {
     devCheck(0);
 
@@ -63,7 +60,10 @@ void Simulation::init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, SPt
     this->gridProvider      = gridProvider;
     this->cudaMemoryManager = cudaMemoryManager;
     this->para              = para;
-    this->cudaKernelManager = CudaKernelManager::make(para);
+    this->lbKernelManager   = std::make_shared<LBKernelManager>(para);
+    this->adKernelManager   = std::make_shared<ADKernelManager>(para);
+    this->bcKernelManager   = std::make_shared<BCKernelManager>(para, bcFactory);
+
 
     para->initParameter();
     para->setRe(para->getVelocityLB() * (real)1.0 / para->getViscosityLB());
@@ -100,19 +100,19 @@ void Simulation::init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, SPt
         para->getParD()->diffusivity = para->getParH()->diffusivity;
         cudaMemoryManager->cudaAllocConcentrationDistributions();
         cudaMemoryManager->cudaAllocConcentration();
-        setInitialNodeValuesAD(para, cudaMemoryManager);
+        adKernelManager->setInitialNodeValuesAD(cudaMemoryManager);
     }
 
     //////////////////////////////////////////////////////////////////////////
     // initialize the grid
     output << "init lattice...";
-    initLattice(para);
+    initLattice(para, adKernelManager.get());
     output << "done.\n";
 
     //////////////////////////////////////////////////////////////////////////
     // print initialized grid
     output << "Print files Init...";
-    dataWriter->writeInit(para, cudaMemoryManager, cudaKernelManager);
+    dataWriter->writeInit(para, cudaMemoryManager, lbKernelManager, adKernelManager.get());
     output << "done.\n";
 
     //////////////////////////////////////////////////////////////////////////
@@ -123,6 +123,7 @@ void Simulation::init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, SPt
 void Simulation::run()
 {
     uint timestep;
+    const int level = 0;
     //////////////////////////////////////////////////////////////////////////
     // Timer
     auto timer        = Timer::makeStart();
@@ -135,23 +136,30 @@ void Simulation::run()
     for (timestep = para->getTimestepStart(); timestep <= para->getTimestepEnd(); timestep++) {
         ////////////////////////////////////////////////////////////////////////////////
         // Advection Diffusion calculation ... Advection first -> fluid second
-        if (para->getIsADcalculationOn())
-            calcAD(para);
+        if (para->getIsADcalculationOn()){
+            adKernelManager->runADcollisionKernel();
+            adKernelManager->runADslipBCKernel();
+        }
 
         ////////////////////////////////////////////////////////////////////////////////
         // LBM Kernel
-        cudaKernelManager->runLBMKernel(para);
+        lbKernelManager->runLBMKernel(para);
+
+        ////////////////////////////////////////////////////////////////////////////////
+        // run post-collision boundary conditions
+        this->bcKernelManager->runVelocityBCKernelPost(level);
+        this->bcKernelManager->runNoSlipBCKernelPost(level);
+        this->bcKernelManager->runSlipBCKernelPost(level);
+        this->bcKernelManager->runGeoBCKernelPost(level);
 
         ////////////////////////////////////////////////////////////////////////////////
-        // velocity boundary condition
-        if (para->getParD()->numberOfVeloBCnodes > 1)
-            cudaKernelManager->runVelocityBCKernel(para);
+        // swap between even and odd timestep
+        para->getParD()->isEvenTimestep = ! para->getParD()->isEvenTimestep;
 
         ////////////////////////////////////////////////////////////////////////////////
-        if (para->getParD()->isEvenTimestep)
-            para->getParD()->isEvenTimestep = false;
-        else
-            para->getParD()->isEvenTimestep = true;
+        //  run pre-collision boundary conditions
+        this->bcKernelManager->runPressureBCKernelPre(level);
+
         ////////////////////////////////////////////////////////////////////////////////
         // File IO and calculation of MNUPS(million node updates per second)
         if (para->getTimestepOut() > 0 && timestep % para->getTimestepOut() == 0 &&
@@ -169,7 +177,7 @@ void Simulation::run()
             // IO
             if (para->getPrintFiles()) {
                 output << "File IO for t=" << timestep << "...";
-                dataWriter->writeTimestep(para, cudaMemoryManager, cudaKernelManager, timestep);
+                dataWriter->writeTimestep(para, cudaMemoryManager, lbKernelManager, adKernelManager.get(), timestep);
                 output << "done.\n";
             }
             timer->start();
@@ -194,10 +202,16 @@ void Simulation::free()
     cudaMemoryManager->cudaFreeSP();
     cudaMemoryManager->cudaFreeNeighborWSB();
 
-    if (para->getParH()->numberOfVeloBCnodes > 1)
+    if (para->getParH()->velocityBC.numberOfBCnodes > 1)
+        this->cudaMemoryManager->cudaFreeVeloBC();
+
+    if (para->getParH()->slipBC.numberOfBCnodes > 1)
+        this->cudaMemoryManager->cudaFreeSlipBC();
+
+    if (para->getParH()->noSlipBC.numberOfBCnodes > 1)
         this->cudaMemoryManager->cudaFreeVeloBC();
 
-    if (para->getParH()->numberOfSlipBCnodes > 1)
+    if (para->getParH()->pressureBC.numberOfBCnodes > 1)
         this->cudaMemoryManager->cudaFreeSlipBC();
 
     cudaMemoryManager->cudaFreeForcing();
diff --git a/src/gpu/VirtualFluids_GPU/LBM/Simulation.h b/src/gpu/VirtualFluids_GPU/LBM/Simulation.h
index 569a4b63e4c263eceb3c302d6c022aa930292c6f..ca61f982875d8e4c8d4c50c2dd3870b19d266fd1 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/Simulation.h
+++ b/src/gpu/VirtualFluids_GPU/LBM/Simulation.h
@@ -33,13 +33,16 @@
 #ifndef _SIMULATION_H_
 #define _SIMULATION_H_
 
+#include "BoundaryConditions/BoundaryConditionFactory.h"
 #include "Output/LogWriter.hpp"
 #include "VirtualFluids_GPU_export.h"
-#include <PointerDefinitions.h>
+#include "PointerDefinitions.h"
 
 //! \brief Class forwarding for CudaMemoryManager, Parameter, GridProvider and DataWriter
 class CudaMemoryManager;
-class CudaKernelManager;
+class LBKernelManager;
+class BCKernelManager;
+class ADKernelManager;
 class Parameter;
 class GridProvider;
 class DataWriter;
@@ -49,15 +52,11 @@ class DataWriter;
 class VIRTUALFLUIDS_GPU_EXPORT Simulation
 {
 public:
-    //! Class default constructor
-    Simulation();
-    //! Class destructor
-    ~Simulation();
     //! \brief includes the time loop over all LB-timesteps
     void run();
     //! \brief initialize the lattice (incl. distribution functions)
     void init(SPtr<Parameter> para, SPtr<GridProvider> gridProvider, SPtr<DataWriter> dataWriter,
-              SPtr<CudaMemoryManager> cudaMemoryManager);
+              SPtr<CudaMemoryManager> cudaMemoryManager, BoundaryConditionFactory *bcFactory);
     //! \brief frees the pinned host memory
     void free();
 
@@ -74,7 +73,11 @@ protected:
     SPtr<DataWriter> dataWriter;
     //! \property cudaMemoryManager is a shared pointer to an object of CudaMemoryManager
     SPtr<CudaMemoryManager> cudaMemoryManager;
-    //! \property cudaKernelManager is a shared pointer to an object of CudaKernelManager
-    SPtr<CudaKernelManager> cudaKernelManager;
+    //! \property cudaKernelManager is a shared pointer to an object of LBKernelManager
+    SPtr<LBKernelManager> lbKernelManager;
+    //! \property adKernelManager is a shared pointer to an object of ADKernelManager
+    SPtr<ADKernelManager> adKernelManager;
+    //! \property bcKernelManager is a shared pointer to an object of BCKernelManager
+    SPtr<BCKernelManager> bcKernelManager;
 };
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/Output/DataWriter.h b/src/gpu/VirtualFluids_GPU/Output/DataWriter.h
index a476195095d525c2970a17c76193882b3ceb5e24..41fbfb5056aa8c11020f9b70001516575bae9956 100644
--- a/src/gpu/VirtualFluids_GPU/Output/DataWriter.h
+++ b/src/gpu/VirtualFluids_GPU/Output/DataWriter.h
@@ -40,7 +40,8 @@
 //! \brief Class forwarding for CudaMemoryManager and Parameter
 class Parameter;
 class CudaMemoryManager;
-class CudaKernelManager;
+class LBKernelManager;
+class ADKernelManager;
 
 //! \class FileWriter
 //! \brief manages the VTK output
@@ -48,27 +49,29 @@ class DataWriter
 {
 public:
 	//! Class default constructor
-	VIRTUALFLUIDS_GPU_EXPORT DataWriter() {}
+	VIRTUALFLUIDS_GPU_EXPORT DataWriter() = default;
 	//! Class destructor
-	virtual VIRTUALFLUIDS_GPU_EXPORT ~DataWriter() {}
+	virtual VIRTUALFLUIDS_GPU_EXPORT ~DataWriter() = default;
 
 	//! \brief write the initialization step to VTK file(s)
 	//! \param para instance of classParameter
 	//! \param cudaMemoryManager instance of class CudaMemoryManager
-    //! \param cudaKernelManager instance of class CudaKernelManager
+    //! \param cudaKernelManager instance of class LBKernelManager
     virtual void VIRTUALFLUIDS_GPU_EXPORT writeInit(
 		SPtr<Parameter> para, 
 		SPtr<CudaMemoryManager> cudaMemoryManager, 
-		SPtr<CudaKernelManager> cudaKernelManager) = 0;
+		SPtr<LBKernelManager> cudaKernelManager,
+		ADKernelManager* ADKernelManager) = 0;
 	//! \brief write time step to VTK file(s)
 	//! \param para instance of classParameter
     //! \param cudaMemoryManager instance of class CudaMemoryManager
-    //! \param cudaKernelManager instance of class CudaKernelManager
+    //! \param cudaKernelManager instance of class LBKernelManager
     //! \param timestep of the simulation
 	virtual void VIRTUALFLUIDS_GPU_EXPORT writeTimestep(
 		SPtr<Parameter> para, 
 		SPtr<CudaMemoryManager> cudaMemoryManager, 
-		SPtr<CudaKernelManager> cudaKernelManager, 
+		SPtr<LBKernelManager> cudaKernelManager,
+		ADKernelManager* ADKernelManager, 
 		uint timestep) = 0;
 };
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp b/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
index 8f77ce0ef5388303d621e09696ac83b71a0f7cce..276dbfc2bb6d65a774719acb931727cb5a03b731 100644
--- a/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
+++ b/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
@@ -34,19 +34,19 @@
 #include "GPU/CudaMemoryManager.h"
 #include "Parameter/Parameter.h"
 #include "basics/writer/WbWriterVtkXmlBinary.h"
-#include "AdvectionDiffusion/AdvectionDiffusion.h"
-#include "GPU/CudaKernelManager.h"
+#include "KernelManager/ADKernelManager.h"
+#include "KernelManager/LBKernelManager.h"
 
-void FileWriter::writeInit(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager, SPtr<CudaKernelManager> cudaKernelManager)
+void FileWriter::writeInit(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager, SPtr<LBKernelManager> cudaKernelManager, ADKernelManager* adKernelManager)
 {
     uint timestep = 0;
-    writeTimestep(para, cudaMemoryManager, cudaKernelManager, timestep);
+    writeTimestep(para, cudaMemoryManager, cudaKernelManager, adKernelManager, timestep);
 }
 
-void FileWriter::writeTimestep(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager, SPtr<CudaKernelManager> cudaKernelManager, uint timestep)
+void FileWriter::writeTimestep(SPtr<Parameter> para, SPtr<CudaMemoryManager> cudaMemoryManager, SPtr<LBKernelManager> cudaKernelManager, ADKernelManager* adKernelManager, uint timestep)
 {
     if (para->getIsADcalculationOn())
-        printAD(para, cudaMemoryManager);
+        adKernelManager->printAD(cudaMemoryManager);
 
     cudaKernelManager->calculateMacroscopicValues(para);
     cudaMemoryManager->cudaCopyDataToHost();
@@ -82,12 +82,12 @@ void FileWriter::writeUnstrucuredGridLT(SPtr<Parameter> para, std::vector<std::s
     std::vector< UbTupleFloat3 > nodes;
     std::vector< UbTupleUInt8 > cells;
     std::vector< std::string > nodedatanames;
-    nodedatanames.push_back("Press");
-    nodedatanames.push_back("DRho");
-    nodedatanames.push_back("Vx");
-    nodedatanames.push_back("Vy");
-    nodedatanames.push_back("Vz");
-    nodedatanames.push_back("Geometry");
+    nodedatanames.emplace_back("Press");
+    nodedatanames.emplace_back("DRho");
+    nodedatanames.emplace_back("Vx");
+    nodedatanames.emplace_back("Vy");
+    nodedatanames.emplace_back("Vz");
+    nodedatanames.emplace_back("Geometry");
     unsigned int number1, number2, number3, number4, number5, number6, number7, number8;
     unsigned int dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
     bool neighborsAreFluid;
@@ -185,13 +185,13 @@ void FileWriter::writeUnstrucuredGridAD(SPtr<Parameter> para, std::vector<std::s
     std::vector<UbTupleFloat3> nodes;
     std::vector<UbTupleUInt8> cells;
     std::vector<std::string> nodedatanames;
-    nodedatanames.push_back("Press");
-    nodedatanames.push_back("DRho");
-    nodedatanames.push_back("Vx");
-    nodedatanames.push_back("Vy");
-    nodedatanames.push_back("Vz");
-    nodedatanames.push_back("Geometry");
-    nodedatanames.push_back("Concentration");
+    nodedatanames.emplace_back("Press");
+    nodedatanames.emplace_back("DRho");
+    nodedatanames.emplace_back("Vx");
+    nodedatanames.emplace_back("Vy");
+    nodedatanames.emplace_back("Vz");
+    nodedatanames.emplace_back("Geometry");
+    nodedatanames.emplace_back("Concentration");
     unsigned int number1, number2, number3, number4, number5, number6, number7, number8;
     unsigned int dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
     bool neighborsAreFluid;
diff --git a/src/gpu/VirtualFluids_GPU/Output/FileWriter.h b/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
index e1dc92e39f19d84b014a20de8d1bc9577cc8c81a..d0121aefe495ca09a54abfbc669a964933659ce7 100644
--- a/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
+++ b/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
@@ -41,49 +41,50 @@
 //! \brief Class forwarding for CudaMemoryManager and Parameter
 class Parameter;
 class CudaMemoryManager;
-class CudaKernelManager;
+class LBKernelManager;
+class ADKernelManager;
 
 //! \class FileWriter derived class of DataWriter
 //! \brief manages the VTK output
 class FileWriter : public DataWriter
 {
 public:
-	//! Class default constructor
-	VIRTUALFLUIDS_GPU_EXPORT FileWriter() {}
-	//! Class destructor
-	VIRTUALFLUIDS_GPU_EXPORT ~FileWriter() {}
+    //! Class default constructor
+    VIRTUALFLUIDS_GPU_EXPORT FileWriter() = default;
 
-	//! \brief write the initialization step to VTK file(s)
-	//! \param para instance of classParameter
-	//! \param cudaMemoryManager instance of class CudaMemoryManager
-    //! \param cudaKernelManager instance of class CudaKernelManager
+    //! \brief write the initialization step to VTK file(s)
+    //! \param para instance of classParameter
+    //! \param cudaMemoryManager instance of class CudaMemoryManager
+    //! \param cudaKernelManager instance of class LBKernelManager
     void VIRTUALFLUIDS_GPU_EXPORT writeInit(
-		SPtr<Parameter> para, 
-		SPtr<CudaMemoryManager> cudaMemoryManager, 
-		SPtr<CudaKernelManager> cudaKernelManager) override;
-	//! \brief write time step to VTK file(s)
-	//! \param para instance of classParameter
+        SPtr<Parameter> para, 
+        SPtr<CudaMemoryManager> cudaMemoryManager, 
+        SPtr<LBKernelManager> cudaKernelManager,
+        ADKernelManager* adKernelManager) override;
+    //! \brief write time step to VTK file(s)
+    //! \param para instance of classParameter
     //! \param cudaMemoryManager instance of class CudaMemoryManager
-    //! \param cudaKernelManager instance of class CudaKernelManager
+    //! \param cudaKernelManager instance of class LBKernelManager
     //! \param timestep of the simulation
-	void VIRTUALFLUIDS_GPU_EXPORT writeTimestep(
-		SPtr<Parameter> para, 
-		SPtr<CudaMemoryManager> cudaMemoryManager, 
-		SPtr<CudaKernelManager> cudaKernelManager, 
-		uint timestep) override;
+    void VIRTUALFLUIDS_GPU_EXPORT writeTimestep(
+        SPtr<Parameter> para,
+        SPtr<CudaMemoryManager> cudaMemoryManager,
+        SPtr<LBKernelManager> cudaKernelManager,
+        ADKernelManager* adKernelManager,
+        uint timestep) override;
 
 private:
-	//! \brief write binary VTK file as unstructured grid
-	//! \param para instance of classParameter
-	//! \param fname vector of strings with path and prefix of written files
-	void VIRTUALFLUIDS_GPU_EXPORT writeUnstrucuredGridLT(SPtr<Parameter> para, std::vector<std::string >& fname);
+    //! \brief write binary VTK file as unstructured grid
+    //! \param para instance of classParameter
+    //! \param fname vector of strings with path and prefix of written files
+    void VIRTUALFLUIDS_GPU_EXPORT writeUnstrucuredGridLT(SPtr<Parameter> para, std::vector<std::string >& fname);
     //! \brief write binary VTK file as unstructured grid with concentration of Advection Diffusion component
     //! \param para instance of classParameter
     //! \param fname vector of strings with path and prefix of written files
     void VIRTUALFLUIDS_GPU_EXPORT writeUnstrucuredGridAD(SPtr<Parameter> para, std::vector<std::string> &fname);
     //! \brief checks for periodic cells
-	//! \param para instance of classParameter
-	//! \param number 2, 1, 3 and 5 are the possible periodic neighbors
-	bool VIRTUALFLUIDS_GPU_EXPORT isPeriodicCell(SPtr<Parameter> para, uint number2, uint number1, uint number3, uint number5);
+    //! \param para instance of classParameter
+    //! \param number 2, 1, 3 and 5 are the possible periodic neighbors
+    bool VIRTUALFLUIDS_GPU_EXPORT isPeriodicCell(SPtr<Parameter> para, uint number2, uint number1, uint number3, uint number5);
 };
 #endif
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
index b8598910a62198afe13251d34b19950dca53fe04..732ce77a0d95b2a9c60934e32bbb98110ade94b0 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
+++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
@@ -32,18 +32,15 @@
 //=======================================================================================
 #include "Parameter.h"
 
+#include <memory>
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
-
-SPtr<Parameter> Parameter::make()
-{
-    return SPtr<Parameter>(new Parameter());
-}
+#include "Core/Logger/Logger.h"
 
 Parameter::Parameter()
 {
-    this->setOutputPath("C:/Output/");
+    this->setOutputPath("output/");
 
     this->setOutputPrefix("MyFile");
 
@@ -73,7 +70,7 @@ Parameter::Parameter()
 
     this->setPressureRatio((real)1.0);
 
-    this->setPathAndFilename(this->getOutputPath() + "/" + this->getOutputPrefix());
+    this->setPathAndFilename(this->getOutputPath() + this->getOutputPrefix());
 
     this->setlimitOfNodesForVTK((uint)30000000);
 
@@ -81,15 +78,40 @@ Parameter::Parameter()
     // Advection Diffusion
     this->setIsADcalculationOn(false);
 }
-Parameter::~Parameter()
+
+Parameter::Parameter(const vf::basics::ConfigurationFile &configData) : Parameter()
 {
+    readConfigData(configData);
 }
-Parameter* Parameter::instance = 0;
-Parameter* Parameter::getInstanz()
-{
-    if( instance == 0 )
-        instance = new Parameter();
-    return instance;
+
+void Parameter::readConfigData(const vf::basics::ConfigurationFile &configData){
+
+    if (configData.contains("OutputPath"))
+        this->setOutputPath(configData.getValue<std::string>("OutputPath"));
+
+    // deprecated, this is only in here for backward compatibility
+    if (configData.contains("Path")){
+        *logging::out << logging::Logger::INFO_INTERMEDIATE << "The config option \"Path\" is deprecated, please use \"OutputPath\" instead." << "\n";
+        this->setOutputPath(configData.getValue<std::string>("Path"));
+    }
+
+    if (configData.contains("OutputPrefix"))
+        this->setOutputPrefix(configData.getValue<std::string>("OutputPrefix"));
+
+    // deprecated, this is only in here for backward compatibility
+    if (configData.contains("Prefix")){
+        *logging::out << logging::Logger::INFO_INTERMEDIATE << "The config option \"Prefix\" is deprecated, please use \"OutputPrefix\" instead." << "\n";
+        this->setOutputPath(configData.getValue<std::string>("Prefix"));
+    }
+
+    // overwrite PathAndFilename when OutputPath or OutputPrefix are set in the config file
+    this->setPathAndFilename(this->getOutputPath() + this->getOutputPrefix());
+
+    if (configData.contains("TimeEnd"))
+        this->setTimestepEnd(configData.getValue<int>("TimeEnd"));
+
+    if (configData.contains("TimeOut"))
+        this->setTimestepOut(configData.getValue<int>("TimeOut"));
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -98,7 +120,7 @@ Parameter* Parameter::getInstanz()
 void Parameter::initParameter()
 {
     //host
-    parametersOnHost                          = new ParameterStruct;
+    parametersOnHost                          = std::make_shared<ParameterStruct>();
     parametersOnHost->numberofthreads         = 64;
     parametersOnHost->omega                   = (real)1.0/((real)3.0*this->viscosityLB+(real)0.5);
     parametersOnHost->isEvenTimestep          = true;
@@ -106,7 +128,7 @@ void Parameter::initParameter()
     parametersOnHost->diffusivity = (real)0.01;
 
     //device
-    parametersOnDevice                        = new ParameterStruct;
+    parametersOnDevice                        = std::make_shared<ParameterStruct>();
     parametersOnDevice->numberofthreads       = parametersOnHost->numberofthreads;
     parametersOnDevice->omega                 = parametersOnHost->omega;
     parametersOnDevice->isEvenTimestep        = parametersOnHost->isEvenTimestep;
@@ -140,6 +162,10 @@ void Parameter::setTimestepStartOut(uint timestepStartOut)
 }
 void Parameter::setOutputPath(std::string outputPath)
 {
+    // add missing slash to outputPath
+    if (outputPath.back() != '/')
+        outputPath += "/";
+
     this->outputPath = outputPath;
 }
 void Parameter::setOutputPrefix(std::string outputPrefix)
@@ -224,11 +250,11 @@ uint Parameter::getlimitOfNodesForVTK()
 {
     return this->limitOfNodesForVTK;
 }
-ParameterStruct* Parameter::getParD()
+std::shared_ptr<ParameterStruct> Parameter::getParD(const int level)
 {
     return this->parametersOnDevice;
 }
-ParameterStruct* Parameter::getParH()
+std::shared_ptr<ParameterStruct> Parameter::getParH(const int level)
 {
     return this->parametersOnHost;
 }
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
index 3e212482de466c4c4451d9d02d2ce6433a02edce..347a04e0cd7dac4924542d17bb1a9ad062d1cb01 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
+++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
@@ -37,6 +37,7 @@
 #include "LBM/LB.h"
 #include "PointerDefinitions.h"
 #include "VirtualFluids_GPU_export.h"
+#include "basics/config/ConfigurationFile.h"
 
 //! \struct ParameterStruct
 //! \brief struct holds and manages the LB-parameter of the simulation that correspond to a certain level
@@ -76,20 +77,20 @@ struct ParameterStruct{
     //////////////////////////////////////////////////////////////////////////
     //! \brief stores the slip boundary condition data
     QforBoundaryConditions slipBC;
-    //! \brief number of lattice nodes for the slip boundary condition
-    uint numberOfSlipBCnodes;
     //////////////////////////////////////////////////////////////////////////
     //! \brief stores the velocity boundary condition data
-    QforBoundaryConditions veloBC;
-    //! \brief number of lattice nodes for the velocity boundary condition
-    uint numberOfVeloBCnodes;
+    QforBoundaryConditions velocityBC;
     //////////////////////////////////////////////////////////////////////////
     //! \brief stores the geometry boundary condition data
     QforBoundaryConditions geometryBC;
-    //! \brief number of lattice nodes for the velocity boundary condition
-    uint numberOfgeometryBCnodes;
     //////////////////////////////////////////////////////////////////////////
-    //! \brief sets the forcing uniform on every fluid node in all three space dimensions 
+    //! \brief stores the pressure boundary condition data
+    QforBoundaryConditions pressureBC;
+    //////////////////////////////////////////////////////////////////////////
+    //! \brief stores the no slip boundary condition data
+    QforBoundaryConditions noSlipBC;
+    //////////////////////////////////////////////////////////////////////////
+    //! \brief sets the forcing uniform on every fluid node in all three space dimensions
     real *forcing;
 
     //////////////////////////////////////////////////////////////////////////
@@ -98,7 +99,7 @@ struct ParameterStruct{
     //! \brief stores the diffusivity
     real diffusivity;
     //! \brief stores the value for omega (for the diffusivity)
-    real omegaD;
+    real omegaDiffusivity;
     //! \brief stores a field of concentration values
     real *concentration;
     //! \brief store all distribution functions for the D3Q27 Advection Diffusion field
@@ -111,17 +112,22 @@ class VIRTUALFLUIDS_GPU_EXPORT Parameter
 {
 public:
     ////////////////////////////////////////////////////////////////////////////
-    //! \brief generate a new instance of parameter object
-    static SPtr<Parameter> make();
-    //! \brief returns the instance generate a new instance of parameter object
-    static Parameter* getInstanz();
+    //! \brief generate a new instance of parameter object, sets some defaults
+    Parameter();
+    //! \brief generate a new instance of parameter object using a config file 
+    //! \details calls Parameter(): Variables which are not set in the config files use the defaults
+    Parameter(const vf::basics::ConfigurationFile &configData);
+    
+    ~Parameter() = default;
+
     //! \brief Pointer to instance of ParameterStruct - stored on Host System
-    ParameterStruct* getParH();
+    std::shared_ptr<ParameterStruct> getParH(const int level = 0);
+
     //! \brief Pointer to instance of ParameterStruct - stored on Device (GPU)
-    ParameterStruct* getParD();
+    std::shared_ptr<ParameterStruct> getParD(const int level = 0);
 
     //////////////////////////////////////////////////////////////////////////
-    //! \brief initialization of necessary parameters at startup
+    //! \brief initialization of necessary parameters at simulation startup
     void initParameter();
 
     //////////////////////////////////////////////////////////////////////////
@@ -149,8 +155,10 @@ public:
     //! \param string "oPrefix" represents the file-name-prefix
     void setOutputPrefix(std::string outputPrefix);
     //! \brief sets the complete string for the vtk-files with results 
-    //! \param string "fname" represents the combination of path and prefix
+    //! \param string "pathAndFilename" represents the combination of path and prefix
     void setPathAndFilename(std::string pathAndFilename);
+    //! \brief sets the path for reading and writing the grid
+    void setGridPath(std::string gridPath);
     //! \brief sets the status, if Advection Diffusion should be calculated
     //! \param if calcAD is true, the Advection Diffusion will be calculated
     void setIsADcalculationOn(bool calcAD);
@@ -255,13 +263,10 @@ public:
     void setInitialConditionAD(std::function<void(real, real, real, real &)> initialConditionAD);
     std::function<void(real, real, real, real &)> &getInitialConditionAD();
 
-    //////////////////////////////////////////////////////////////////////////
-    //! Class destructor
-    ~Parameter();
-protected:
 private:
-    //! \brief instance of parameter object 
-    static Parameter* instance;
+    //! read configuration data from a config file
+    void readConfigData(const vf::basics::ConfigurationFile &configData);
+private:
     //! \brief stencil for the LB simulation, number of node neighbors
     int D3Qxx;
     //! \brief limit of nodes, that can be written to a binary unstructured grid VTK file  
@@ -303,13 +308,9 @@ private:
     std::function<void(real, real, real, real &)> initialConditionAD;
 
     //! \brief pointer to LB-parameter struct on host system
-    ParameterStruct* parametersOnHost;
+    std::shared_ptr<ParameterStruct> parametersOnHost;
     //! \brief pointer to LB-parameter struct on device/GPU
-    ParameterStruct* parametersOnDevice;
-
-    //! Class default constructor
-    Parameter();
-    //Parameter(const Parameter&);
+    std::shared_ptr<ParameterStruct> parametersOnDevice;
 };
 
 #endif
diff --git a/src/lbm/CumulantChimera.cpp b/src/lbm/CumulantChimera.cpp
index 65dc9b1f82f409447fda54fc0bc5f460533aad1b..e1c27f90b6611640d8e5db47c9432268f5f58f15 100644
--- a/src/lbm/CumulantChimera.cpp
+++ b/src/lbm/CumulantChimera.cpp
@@ -181,7 +181,7 @@ __host__ __device__ void cumulantChimera(KernelParameter parameter, RelaxationRa
     setRelaxationRates(omega, OxxPyyPzz, OxyyPxzz, OxyyMxzz, Oxyz, O4, O5, O6);
 
     ////////////////////////////////////////////////////////////////////////////////////
-    //! - A and B: parameters for fourth order convergence of the diffusion term according to Eq. (114) and (115) 
+    //! - A and B: parameters for fourth order convergence of the diffusion term according to Eq. (115) and (116) 
     //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05  040 ]</b></a>
     //! with simplifications assuming \f$ \omega_2 = 1.0 \f$ (modify for different bulk viscosity).
     //!
diff --git a/src/lbm/constants/D3Q27.h b/src/lbm/constants/D3Q27.h
index 0b2cbfdd44e84af590fa2c2be4bf319cbfd4c815..d13da3d610ec69cb5eb5e553491ba047d0b09890 100644
--- a/src/lbm/constants/D3Q27.h
+++ b/src/lbm/constants/D3Q27.h
@@ -1,13 +1,12 @@
 #ifndef LBM_D3Q27_H
 #define LBM_D3Q27_H
 
-namespace vf
-{
-namespace lbm
-{
-namespace dir
+namespace vf::lbm::dir
 {
 
+static constexpr int STARTDIR = 0;
+static constexpr int ENDDIR   = 26;
+
 static constexpr int E    = 0;
 static constexpr int W    = 1;
 static constexpr int N    = 2;
@@ -65,7 +64,4 @@ static constexpr int MMM = 25;
 static constexpr int ZZZ = 26;
 
 }
-}
-}
-
 #endif