diff --git a/apps/gpu/FlowAroundSphere/CMakeLists.txt b/apps/gpu/FlowAroundSphere/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..187c9cc57539ca1a6c74642612481c9cc7040237
--- /dev/null
+++ b/apps/gpu/FlowAroundSphere/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(LidDrivenCavityGPU LANGUAGES CUDA CXX)
+
+vf_add_library(BUILDTYPE binary PRIVATE_LINK basics GridGenerator VirtualFluids_GPU GksMeshAdapter GksGpu FILES FlowAroundSphere.cpp)
diff --git a/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp b/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a11e1c692b896503ee0cabd01e8de993c3de49be
--- /dev/null
+++ b/apps/gpu/FlowAroundSphere/FlowAroundSphere.cpp
@@ -0,0 +1,353 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 LidDrivenCavity.cpp
+//! \ingroup Applications
+//! \author Martin Schoenherr, Stephan Lenz
+//=======================================================================================
+#define _USE_MATH_DEFINES
+#include <exception>
+#include <fstream>
+#include <iostream>
+#include <math.h>
+#include <memory>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "Core/DataTypes.h"
+#include "Core/LbmOrGks.h"
+#include "Core/Logger/Logger.h"
+#include "Core/VectorTypes.h"
+#include "PointerDefinitions.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "GridGenerator/grid/BoundaryConditions/Side.h"
+#include "GridGenerator/grid/GridBuilder/LevelGridBuilder.h"
+#include "GridGenerator/grid/GridBuilder/MultipleGridBuilder.h"
+#include "GridGenerator/grid/GridFactory.h"
+#include "GridGenerator/geometries/Sphere/Sphere.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "VirtualFluids_GPU/DataStructureInitializer/GridProvider.h"
+#include "VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h"
+#include "VirtualFluids_GPU/GPU/CudaMemoryManager.h"
+#include "VirtualFluids_GPU/LBM/Simulation.h"
+#include "VirtualFluids_GPU/Output/FileWriter.h"
+#include "VirtualFluids_GPU/Parameter/Parameter.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "GksMeshAdapter/GksMeshAdapter.h"
+
+#include "GksGpu/DataBase/DataBase.h"
+#include "GksGpu/Initializer/Initializer.h"
+#include "GksGpu/Parameters/Parameters.h"
+
+#include "GksGpu/FlowStateData/FlowStateDataConversion.cuh"
+
+#include "GksGpu/BoundaryConditions/BoundaryCondition.h"
+#include "GksGpu/BoundaryConditions/IsothermalWall.h"
+
+#include "GksGpu/TimeStepping/NestedTimeStep.h"
+
+#include "GksGpu/Analyzer/ConvergenceAnalyzer.h"
+#include "GksGpu/Analyzer/CupsAnalyzer.h"
+
+#include "GksGpu/CudaUtility/CudaUtility.h"
+
+#include "GksGpu/Output/VtkWriter.h"
+
+int main(int argc, char *argv[])
+{
+    try {
+        //////////////////////////////////////////////////////////////////////////
+        // Simulation parameters
+        //////////////////////////////////////////////////////////////////////////
+        std::string path("/output/DrivenCavity");
+        std::string simulationName("LidDrivenCavity");
+
+        const real L        = 1.0;
+        const real Re       = 1000.0;
+        const real velocity = 1.0;
+        const real dt       = (real)0.5e-3;
+        const uint nx       = 64;
+
+        const uint timeStepOut = 10000;
+        const uint timeStepEnd = 250000;
+
+        // switch between LBM and GKS solver here
+        // LbmOrGks lbmOrGks = GKS;
+        LbmOrGks lbmOrGks = LBM;
+
+        //////////////////////////////////////////////////////////////////////////
+        // setup logger
+        //////////////////////////////////////////////////////////////////////////
+
+        logging::Logger::addStream(&std::cout);
+        logging::Logger::setDebugLevel(logging::Logger::Level::INFO_LOW);
+        logging::Logger::timeStamp(logging::Logger::ENABLE);
+        logging::Logger::enablePrintedRankNumbers(logging::Logger::ENABLE);
+
+        //////////////////////////////////////////////////////////////////////////
+        // setup gridGenerator
+        //////////////////////////////////////////////////////////////////////////
+
+        auto gridBuilder = MultipleGridBuilder::makeShared();
+
+        //////////////////////////////////////////////////////////////////////////
+        // 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);
+
+        // use primitive
+        Object* sphere = new Sphere(0.0, 0.0, 0.0, 1.0);
+        // use stl
+        // Object* sphere = TriangularMesh::make("stl/sphere.stl");
+        gridBuilder->addGeometry(sphere);
+
+        gridBuilder->setPeriodicBoundaryCondition(false, false, false);
+
+        gridBuilder->buildGrids(lbmOrGks, false);
+
+        //////////////////////////////////////////////////////////////////////////
+        // branch between LBM and GKS
+        //////////////////////////////////////////////////////////////////////////
+
+        if (lbmOrGks == LBM) {
+            SPtr<Parameter> para = Parameter::make();
+
+            //////////////////////////////////////////////////////////////////////////
+            // compute parameters in lattice units
+            //////////////////////////////////////////////////////////////////////////
+
+            const real velocityLB = velocity * dt / dx; // LB units
+
+            const real vx = velocityLB / sqrt(2.0); // LB units
+            const real vy = velocityLB / sqrt(2.0); // LB units
+
+            const real viscosityLB = nx * 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";
+
+            //////////////////////////////////////////////////////////////////////////
+            // set parameters
+            //////////////////////////////////////////////////////////////////////////
+
+            para->setOutputPath(path);
+            para->setOutputPrefix(simulationName);
+
+            para->setPathAndFilename(para->getOutputPath() + "/" + para->getOutputPrefix());
+
+            para->setPrintFiles(true);
+
+            para->setVelocityLB(velocityLB);
+            para->setViscosityLB(viscosityLB);
+
+            para->setVelocityRatio(velocity / velocityLB);
+
+            para->setTimestepOut(timeStepOut);
+            para->setTimestepEnd(timeStepEnd);
+
+            //////////////////////////////////////////////////////////////////////////
+            // set boundary conditions
+            //////////////////////////////////////////////////////////////////////////
+
+            gridBuilder->setNoSlipBoundaryCondition(SideType::PX);
+            gridBuilder->setNoSlipBoundaryCondition(SideType::MX);
+            gridBuilder->setNoSlipBoundaryCondition(SideType::PY);
+            gridBuilder->setNoSlipBoundaryCondition(SideType::MY);
+            gridBuilder->setVelocityBoundaryCondition(SideType::PZ, vx, vy, 0.0);
+            gridBuilder->setNoSlipBoundaryCondition(SideType::MZ);
+            gridBuilder->setVelocityBoundaryCondition(SideType::GEOMETRY, 0.0, 0.0, 0.0);
+
+            //////////////////////////////////////////////////////////////////////////
+            // set copy mesh to simulation
+            //////////////////////////////////////////////////////////////////////////
+
+            SPtr<CudaMemoryManager> cudaMemoryManager = CudaMemoryManager::make(para);
+
+            SPtr<GridProvider> gridGenerator = GridProvider::makeGridGenerator(gridBuilder, para, cudaMemoryManager);
+
+            //////////////////////////////////////////////////////////////////////////
+            // run simulation
+            //////////////////////////////////////////////////////////////////////////
+
+            Simulation sim;
+            SPtr<FileWriter> fileWriter = SPtr<FileWriter>(new FileWriter());
+            sim.init(para, gridGenerator, fileWriter, cudaMemoryManager);
+            sim.run();
+            sim.free();
+        } else {
+            CudaUtility::setCudaDevice(0);
+
+            Parameters parameters;
+
+            //////////////////////////////////////////////////////////////////////////
+            // compute remaining parameters
+            //////////////////////////////////////////////////////////////////////////
+
+            const real vx = velocity / sqrt(2.0);
+            const real vy = velocity / sqrt(2.0);
+
+            parameters.K  = 2.0;
+            parameters.Pr = 1.0;
+
+            const real Ma = (real)0.1;
+
+            real rho = 1.0;
+
+            real cs     = velocity / Ma;
+            real lambda = c1o2 * ((parameters.K + 5.0) / (parameters.K + 3.0)) / (cs * cs);
+
+            const real mu = velocity * L * rho / Re;
+
+            *logging::out << logging::Logger::INFO_HIGH << "mu  = " << mu << " m^2/s\n";
+
+            *logging::out << logging::Logger::INFO_HIGH << "CFL = " << dt * (velocity + cs) / dx << "\n";
+
+            //////////////////////////////////////////////////////////////////////////
+            // set parameters
+            //////////////////////////////////////////////////////////////////////////
+
+            parameters.mu = mu;
+
+            parameters.dt = dt;
+            parameters.dx = dx;
+
+            parameters.lambdaRef = lambda;
+
+            //////////////////////////////////////////////////////////////////////////
+            // set copy mesh to simulation
+            //////////////////////////////////////////////////////////////////////////
+
+            GksMeshAdapter meshAdapter(gridBuilder);
+
+            meshAdapter.inputGrid();
+
+            auto dataBase = std::make_shared<DataBase>("GPU");
+
+            //////////////////////////////////////////////////////////////////////////
+            // set boundary conditions
+            //////////////////////////////////////////////////////////////////////////
+
+            SPtr<BoundaryCondition> bcLid =
+                std::make_shared<IsothermalWall>(dataBase, Vec3(vx, vy, 0.0), lambda, false);
+            SPtr<BoundaryCondition> bcWall =
+                std::make_shared<IsothermalWall>(dataBase, Vec3(0.0, 0.0, 0.0), lambda, false);
+
+            bcLid->findBoundaryCells(meshAdapter, false, [&](Vec3 center) {
+                return center.z > 0.5 && center.x > -0.5 && center.x < 0.5 && center.y > -0.5 && center.y < 0.5;
+            });
+
+            bcWall->findBoundaryCells(meshAdapter, true, [&](Vec3 center) {
+                return center.x < -0.5 || center.x > 0.5 || center.y < -0.5 || center.y > 0.5 || center.z < -0.5;
+            });
+
+            dataBase->boundaryConditions.push_back(bcLid);
+            dataBase->boundaryConditions.push_back(bcWall);
+
+            //////////////////////////////////////////////////////////////////////////
+            // set initial condition and upload mesh and initial condition to GPGPU
+            //////////////////////////////////////////////////////////////////////////
+
+            dataBase->setMesh(meshAdapter);
+
+            Initializer::interpret(dataBase, [&](Vec3 cellCenter) -> ConservedVariables {
+                return toConservedVariables(PrimitiveVariables(rho, 0.0, 0.0, 0.0, lambda), parameters.K);
+            });
+
+            dataBase->copyDataHostToDevice();
+
+            Initializer::initializeDataUpdate(dataBase);
+
+            VtkWriter::write(dataBase, parameters, path + "/" + simulationName + "_0");
+
+            //////////////////////////////////////////////////////////////////////////
+            // set analyzers
+            //////////////////////////////////////////////////////////////////////////
+
+            CupsAnalyzer cupsAnalyzer(dataBase, false, 60.0, true, 10000);
+
+            ConvergenceAnalyzer convergenceAnalyzer(dataBase, 10000);
+
+            cupsAnalyzer.start();
+
+            //////////////////////////////////////////////////////////////////////////
+            // run simulation
+            //////////////////////////////////////////////////////////////////////////
+
+            for (uint iter = 1; iter <= timeStepEnd; iter++) {
+                TimeStepping::nestedTimeStep(dataBase, parameters, 0);
+
+                if (iter % timeStepOut == 0) {
+                    dataBase->copyDataDeviceToHost();
+
+                    VtkWriter::write(dataBase, parameters, path + "/" + simulationName + "_" + std::to_string(iter));
+                }
+
+                int crashCellIndex = dataBase->getCrashCellIndex();
+                if (crashCellIndex >= 0) {
+                    *logging::out << logging::Logger::LOGGER_ERROR
+                                  << "Simulation crashed at CellIndex = " << crashCellIndex << "\n";
+                    dataBase->copyDataDeviceToHost();
+                    VtkWriter::write(dataBase, parameters, path + "/" + simulationName + "_" + std::to_string(iter));
+
+                    break;
+                }
+
+                dataBase->getCrashCellIndex();
+
+                cupsAnalyzer.run(iter, parameters.dt);
+
+                convergenceAnalyzer.run(iter);
+            }
+        }
+    } catch (const std::bad_alloc& e) {
+
+        *logging::out << logging::Logger::LOGGER_ERROR << "Bad Alloc:" << e.what() << "\n";
+    } catch (const std::exception& e) {
+
+        *logging::out << logging::Logger::LOGGER_ERROR << e.what() << "\n";
+    } catch (std::string &s) {
+
+        *logging::out << logging::Logger::LOGGER_ERROR << s << "\n";
+    } catch (...) {
+        *logging::out << logging::Logger::LOGGER_ERROR << "Unknown exception!\n";
+    }
+
+    return 0;
+}
diff --git a/gpu.cmake b/gpu.cmake
index ca3929cc1fdc5d15af4b82cd1158ed5b0ad93d10..440f0e3d5846a3af926291a9f463873140f269f4 100644
--- a/gpu.cmake
+++ b/gpu.cmake
@@ -16,6 +16,7 @@ add_subdirectory(src/gpu/GksMeshAdapter)
 add_subdirectory(src/gpu/GksGpu)
 
 add_subdirectory(apps/gpu/LidDrivenCavityGPU)
+add_subdirectory(apps/gpu/FlowAroundSphere)
 add_subdirectory(apps/gpu/DiluteGravityCurrents_Case1)
 add_subdirectory(apps/gpu/DiluteGravityCurrents_Case2)
 add_subdirectory(apps/gpu/DiluteGravityCurrents_Case3)