diff --git a/3rdParty/jsoncpp/amalgamate.py b/3rdParty/jsoncpp/amalgamate.py
index 9cb2d08ccda7c7d8e87c2e7c54de4a42353812fd..a8ab3894c632845ee620e8f8eef3e35301d56eec 100644
--- a/3rdParty/jsoncpp/amalgamate.py
+++ b/3rdParty/jsoncpp/amalgamate.py
@@ -48,13 +48,13 @@ class AmalgamationFile:
         f.close()
 
 def amalgamate_source(source_top_dir=None,
-                       target_source_path=None,
+                       target_VF_SRC_DIR=None,
                        header_include_path=None):
     """Produces amalgated source.
        Parameters:
            source_top_dir: top-directory
-           target_source_path: output .cpp path
-           header_include_path: generated header path relative to target_source_path.
+           target_VF_SRC_DIR: output .cpp path
+           header_include_path: generated header path relative to target_VF_SRC_DIR.
     """
     print("Amalgating header...")
     header = AmalgamationFile(source_top_dir)
@@ -77,7 +77,7 @@ def amalgamate_source(source_top_dir=None,
     header.add_file("include/json/assertions.h")
     header.add_text("#endif //ifndef JSON_AMALGATED_H_INCLUDED")
 
-    target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path)
+    target_header_path = os.path.join(os.path.dirname(target_VF_SRC_DIR), header_include_path)
     print("Writing amalgated header to %r" % target_header_path)
     header.write_to(target_header_path)
 
@@ -98,7 +98,7 @@ def amalgamate_source(source_top_dir=None,
     header.add_file("include/json/forwards.h")
     header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED")
 
-    target_forward_header_path = os.path.join(os.path.dirname(target_source_path),
+    target_forward_header_path = os.path.join(os.path.dirname(target_VF_SRC_DIR),
                                                forward_header_include_path)
     print("Writing amalgated forward header to %r" % target_forward_header_path)
     header.write_to(target_forward_header_path)
@@ -123,8 +123,8 @@ def amalgamate_source(source_top_dir=None,
     source.add_file(os.path.join(lib_json, "json_value.cpp"))
     source.add_file(os.path.join(lib_json, "json_writer.cpp"))
 
-    print("Writing amalgated source to %r" % target_source_path)
-    source.write_to(target_source_path)
+    print("Writing amalgated source to %r" % target_VF_SRC_DIR)
+    source.write_to(target_VF_SRC_DIR)
 
 def main():
     usage = """%prog [options]
@@ -133,7 +133,7 @@ Generate a single amalgated source and header file from the sources.
     from optparse import OptionParser
     parser = OptionParser(usage=usage)
     parser.allow_interspersed_args = False
-    parser.add_option("-s", "--source", dest="target_source_path", action="store", default="dist/jsoncpp.cpp",
+    parser.add_option("-s", "--source", dest="target_VF_SRC_DIR", action="store", default="dist/jsoncpp.cpp",
         help="""Output .cpp source path. [Default: %default]""")
     parser.add_option("-i", "--include", dest="header_include_path", action="store", default="json/json.h",
         help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""")
@@ -143,7 +143,7 @@ Generate a single amalgated source and header file from the sources.
     options, args = parser.parse_args()
 
     msg = amalgamate_source(source_top_dir=options.top_dir,
-                             target_source_path=options.target_source_path,
+                             target_VF_SRC_DIR=options.target_VF_SRC_DIR,
                              header_include_path=options.header_include_path)
     if msg:
         sys.stderr.write(msg + "\n")
diff --git a/3rdParty/jsoncpp/devtools/tarball.py b/3rdParty/jsoncpp/devtools/tarball.py
index 3c0ba65e711c07172f562eac0960af9abf289f3e..27a9b6f4975d27534b065192c69d9e444556aa67 100644
--- a/3rdParty/jsoncpp/devtools/tarball.py
+++ b/3rdParty/jsoncpp/devtools/tarball.py
@@ -37,13 +37,13 @@ def make_tarball(tarball_path, sources, base_dir, prefix_dir=''):
     with closing(tarfile.TarFile.open(tarball_path, 'w:gz',
             compresslevel=compression)) as tar:
         for source in sources:
-            source_path = source
+            VF_SRC_DIR = source
             if os.path.isdir(source):
-                for dirpath, dirnames, filenames in os.walk(source_path):
+                for dirpath, dirnames, filenames in os.walk(VF_SRC_DIR):
                     visit(tar, dirpath, filenames)
             else:
-                path_in_tar = archive_name(source_path)
-                tar.add(source_path, path_in_tar)      # filename, arcname
+                path_in_tar = archive_name(VF_SRC_DIR)
+                tar.add(VF_SRC_DIR, path_in_tar)      # filename, arcname
 
 def decompress(tarball_path, base_dir):
     """Decompress the gzipped tarball into directory base_dir.
diff --git a/CMake/3rd.cmake b/CMake/3rd.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6cc488f94716f7cec973874b0930ed8f9b719d08
--- /dev/null
+++ b/CMake/3rd.cmake
@@ -0,0 +1,5 @@
+include(${VF_CMAKE_DIR}/3rd/boost.cmake)
+include(${VF_CMAKE_DIR}/3rd/cuda.cmake)
+include(${VF_CMAKE_DIR}/3rd/gmock.cmake)
+include(${VF_CMAKE_DIR}/3rd/mpi.cmake)
+include(${VF_CMAKE_DIR}/3rd/OpenMP.cmake)
\ No newline at end of file
diff --git a/CMake/3rd/OpenMP.cmake b/CMake/3rd/OpenMP.cmake
index fce16693d4eb5b8d61187ed198811e44de96f124..bd7781b959907eedb2b5475d6ea106d03641cbe3 100644
--- a/CMake/3rd/OpenMP.cmake
+++ b/CMake/3rd/OpenMP.cmake
@@ -1,13 +1,10 @@
+function (linkOpenMP)
 
-find_package(OpenMP)
-if (OPENMP_FOUND)
-	#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
-	#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
-    #set (CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler ${OpenMP_CXX_FLAGS}")
-endif()
+	find_package(OpenMP REQUIRED)
 
-#message (Cuda Flags: ${OpenMP_CXX_FLAGS})
-vf_get_library_name(library_name)
-if(OpenMP_CXX_FOUND)
-	target_link_libraries(${library_name} PUBLIC OpenMP::OpenMP_CXX)
-endif()
+	if(OpenMP_CXX_FOUND)
+		vf_get_library_name(library_name)
+		target_link_libraries(${library_name} PUBLIC OpenMP::OpenMP_CXX)
+	endif()
+
+endfunction()
\ No newline at end of file
diff --git a/CMake/3rd/boost.cmake b/CMake/3rd/boost.cmake
index fae5cdf658dcb1e33ce25cc45317cd4f524e4829..544ae2d97b3b8ef0277445cf252149986c8dfb3a 100644
--- a/CMake/3rd/boost.cmake
+++ b/CMake/3rd/boost.cmake
@@ -1,4 +1,4 @@
-macro(linkBoost components)
+function(linkBoost components)
   if(BUILD_SHARED_LIBS)
      if (WIN32)
          set(Boost_USE_STATIC_LIBS ON)
@@ -17,8 +17,9 @@ macro(linkBoost components)
 	add_definitions( -DBOOST_ALL_NO_LIB )
 #	add_definitions( -DBOOST_ALL_DYN_LINK )
   endif()
+
   vf_get_library_name(library_name)
   find_package( Boost REQUIRED COMPONENTS ${components})
   target_include_directories(${library_name} PRIVATE ${Boost_INCLUDE_DIR})
   target_link_libraries(${library_name} PRIVATE ${Boost_LIBRARIES})
-endmacro(linkBoost)
+endfunction()
diff --git a/CMake/3rd/cuda.cmake b/CMake/3rd/cuda.cmake
index 32b2e82d4f8ef0e2ec4c258ad19e99ae5938d9fc..f39e4c417134511e4dd8f37cc3a081479d037147 100644
--- a/CMake/3rd/cuda.cmake
+++ b/CMake/3rd/cuda.cmake
@@ -1,4 +1,5 @@
 
+function(linkCUDA)
 
     find_path(CUDA_CUT_INCLUDE_DIR
       helper_cuda.h
@@ -11,8 +12,7 @@
     vf_get_library_name(library_name)
     target_include_directories(${library_name} PRIVATE ${CUDA_INCLUDE_DIRS} ${CUDA_CUT_INCLUDE_DIR})
 
-	#set_property(TARGET ${targetName} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
-	#set_property(TARGET ${targetName} PROPERTY CUDA_64_BIT_DEVICE_CODE ON)
-	
-    #set(CUDA_NVCC_FLAGS "-G" CACHE TYPE INTERNAL FORCE)
-    #set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; -gencode arch=compute_13,code=sm_13 )
+    # set the following properties only for specific targets
+    # set_property(TARGET ${targetName} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
+    # set_property(TARGET ${targetName} PROPERTY CUDA_64_BIT_DEVICE_CODE ON)
+endfunction()
\ No newline at end of file
diff --git a/CMake/3rd/gmock.cmake b/CMake/3rd/gmock.cmake
index b87f284921fe56bb09fa8f4d2c2f29b8733faa0c..205a3b9a17d872d77df114517d8d7dba0de255bf 100644
--- a/CMake/3rd/gmock.cmake
+++ b/CMake/3rd/gmock.cmake
@@ -3,14 +3,15 @@
 #  Note: gmock has to be build by the project itself (Located in 3rd).
 #################################################################################
 
-vf_get_library_test_name(library_name)
-target_link_libraries(${library_name} PRIVATE gtest gmock gmock_main)
+function (linkGMOCK)
+    vf_get_library_test_name(library_name)
+    target_link_libraries(${library_name} PRIVATE gtest gmock gmock_main)
 
-
-if(BUILD_SHARED_LIBS)
-    # add compile option according to
-    # https://github.com/google/googletest/blob/master/googletest/README.md#as-a-shared-library-dll
-    set_target_properties(${library_name}
-            PROPERTIES
-            COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
-endif()
+    if(BUILD_SHARED_LIBS)
+        # add compile option according to
+        # https://github.com/google/googletest/blob/master/googletest/README.md#as-a-shared-library-dll
+        set_target_properties(${library_name}
+                PROPERTIES
+                COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
+    endif()
+endfunction()
\ No newline at end of file
diff --git a/CMake/3rd/mpi.cmake b/CMake/3rd/mpi.cmake
index a3c8826b6fe31f19c7d3d5e42c691796f395b49d..93b3ee386cc46623ed02bbbffb88996328f03e52 100644
--- a/CMake/3rd/mpi.cmake
+++ b/CMake/3rd/mpi.cmake
@@ -1,10 +1,9 @@
+function (linkMPI)
 
+    find_package(MPI REQUIRED)
 
-vf_get_library_name(library_name)
+    vf_get_library_name(library_name)
+    target_include_directories(${library_name} PUBLIC ${MPI_CXX_INCLUDE_PATH})
+    target_link_libraries(${library_name} PRIVATE MPI::MPI_CXX)
 
-find_package(MPI REQUIRED)
-target_include_directories(${library_name} PUBLIC ${MPI_CXX_INCLUDE_PATH})
-
-#target_link_libraries(${library_name} PUBLIC ${MPI_CXX_LIBRARIES})
-
-target_link_libraries(${library_name} PRIVATE MPI::MPI_CXX)
+endfunction()
\ No newline at end of file
diff --git a/CMake/VirtualFluidsMacros.cmake b/CMake/VirtualFluidsMacros.cmake
index 721d56b89ee22f491c4c984de67fa6ee27fa3b74..83274c2fb21a54d8aead43e1215c3f1c53cea4f3 100644
--- a/CMake/VirtualFluidsMacros.cmake
+++ b/CMake/VirtualFluidsMacros.cmake
@@ -222,7 +222,7 @@ function(vf_add_tests)
     target_include_directories(${library_test_name} PRIVATE ${VF_SRC_DIR})
 
     # link googlemock
-    include(${VF_CMAKE_DIR}/3rd/gmock.cmake)
+    linkGMOCK()
 
 endfunction()
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4219695ee306e8fc48c8ac210521a36a460d203b..9faf348c02c77cb89a2e0a2c985cb09b528d3132 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,7 @@ include(CMakePrintHelpers)
 include(${VF_CMAKE_DIR}/CMakeCABMacros.cmake)
 include(${VF_CMAKE_DIR}/FileUtilities.cmake)
 include(${VF_CMAKE_DIR}/VirtualFluidsMacros.cmake)
+include(${VF_CMAKE_DIR}/3rd.cmake)
 
 include(${VF_CMAKE_DIR}/CMakeMacros_old/general/FindCompiler.cmake)
 configure_file(src/basics/VirtualFluidsDefinitions.in.h ${CMAKE_BINARY_DIR}/VirtualFluidsDefinitions.h)
diff --git a/apps/cpu/LidDrivenCavityCPU/CMakeLists.txt b/apps/cpu/LidDrivenCavityCPU/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dbcc5519841fc61e1ae5b454134aa352be4ba9a0
--- /dev/null
+++ b/apps/cpu/LidDrivenCavityCPU/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+
+PROJECT(LidDrivenCavity)
+
+vf_add_library(BUILDTYPE binary DEPENDS VirtualFluidsCore basics FILES LidDrivenCavity.cpp)
+
+vf_get_library_name (library_name)
+target_include_directories(${library_name} PRIVATE ${APPS_ROOT_CPU})
\ No newline at end of file
diff --git a/apps/gpu/LidDrivenCavity/CMakeLists.txt b/apps/gpu/LidDrivenCavity/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f049da0390b5dac566531fbec690c6c81eae579d
--- /dev/null
+++ b/apps/gpu/LidDrivenCavity/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+
+PROJECT(LidDrivenCavity)
+
+
+vf_add_library(BUILDTYPE binary DEPENDS basics GridGenerator VirtualFluids_GPU GksMeshAdapter GksGpu FILES LidDrivenCavity.cpp)
diff --git a/apps/gpu/LidDrivenCavity/LidDrivenCavity.cpp b/apps/gpu/LidDrivenCavity/LidDrivenCavity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f11d8a197be080e59ab1e445596341b579ea66d
--- /dev/null
+++ b/apps/gpu/LidDrivenCavity/LidDrivenCavity.cpp
@@ -0,0 +1,367 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  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 <math.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <stdexcept>
+#include <fstream>
+#include <exception>
+#include <memory>
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "Core/DataTypes.h"
+#include "PointerDefinitions.h"
+#include "Core/LbmOrGks.h"
+#include "Core/VectorTypes.h"
+#include "Core/Logger/Logger.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "GridGenerator/grid/GridBuilder/LevelGridBuilder.h"
+#include "GridGenerator/grid/GridBuilder/MultipleGridBuilder.h"
+#include "GridGenerator/grid/BoundaryConditions/Side.h"
+#include "GridGenerator/grid/GridFactory.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "VirtualFluids_GPU/LBM/Simulation.h"
+#include "VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h"
+#include "VirtualFluids_GPU/DataStructureInitializer/GridProvider.h"
+#include "VirtualFluids_GPU/Parameter/Parameter.h"
+#include "VirtualFluids_GPU/Output/FileWriter.h"
+#include "VirtualFluids_GPU/GPU/CudaMemoryManager.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "GksMeshAdapter/GksMeshAdapter.h"
+
+#include "GksGpu/DataBase/DataBase.h"
+#include "GksGpu/Parameters/Parameters.h"
+#include "GksGpu/Initializer/Initializer.h"
+
+#include "GksGpu/FlowStateData/FlowStateDataConversion.cuh"
+
+#include "GksGpu/BoundaryConditions/BoundaryCondition.h"
+#include "GksGpu/BoundaryConditions/IsothermalWall.h"
+
+#include "GksGpu/TimeStepping/NestedTimeStep.h"
+
+#include "GksGpu/Analyzer/CupsAnalyzer.h"
+#include "GksGpu/Analyzer/ConvergenceAnalyzer.h"
+
+#include "GksGpu/CudaUtility/CudaUtility.h"
+
+#include "GksGpu/Output/VtkWriter.h"
+
+//////////////////////////////////////////////////////////////////////////
+
+int main( int argc, char* argv[])
+{
+    try
+    {
+        //////////////////////////////////////////////////////////////////////////
+        // Simulation parameters
+        //////////////////////////////////////////////////////////////////////////
+        std::string path("./output");
+        std::string simulationName("LidDrivenCavity");
+
+        const real L  = 1.0;
+        const real Re = 1000.0;
+        const real velocity = 1.0;
+        const real dt = 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 gridFactory = GridFactory::make();
+        gridFactory->setGridStrategy(Device::CPU);
+        auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory);
+    
+        //////////////////////////////////////////////////////////////////////////
+        // create grid
+        //////////////////////////////////////////////////////////////////////////
+
+	    real dx = L / real(nx);
+
+	    gridBuilder->addCoarseGrid(-0.5 * L, -0.5 * L, -0.5 * L,
+								    0.5 * L,  0.5 * L,  0.5 * L, dx);
+
+	    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);
+    
+            //////////////////////////////////////////////////////////////////////////
+            // 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 = 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/cpu.cmake b/cpu.cmake
index f472172ba10cf32291efd18e1d00c33f5b312a56..3740f1bce59d7f3c97af33c9e24bf6229c031a87 100644
--- a/cpu.cmake
+++ b/cpu.cmake
@@ -39,7 +39,10 @@ SET(USE_GCC OFF CACHE BOOL "include gcc compiler support") #TODO: why do we need
 SET(USE_HLRN_LUSTRE OFF CACHE BOOL "include HLRN Lustre support")
 SET(USE_DEM_COUPLING OFF CACHE BOOL "PE plugin")
 
+<<<<<<< HEAD
 
+=======
+>>>>>>> feature/clean_3rd_cmake_macros
 #CAB
 include("CMake/CMakeCABMacros.cmake") #TODO: Currently we have to include the CABMacros also here, so that the USE_* are defined in the config files for the cpu version
 #include("CMake/FileUtilities.cmake")
@@ -153,9 +156,9 @@ ENDIF()
 #    add_subdirectory(Plugins/dem_coupling)
 #ENDIF()
 
-add_subdirectory(3rdParty/MuParser)
+add_subdirectory(${VF_THIRD_DIR}/MuParser)
 
 add_subdirectory(src/cpu/VirtualFluidsCore)
 
-set (APPS_ROOT_CPU ${VF_ROOT_DIR}/apps/cpu)
+set (APPS_ROOT_CPU "${VF_ROOT_DIR}/apps/cpu/")
 include(${APPS_ROOT_CPU}/Applications.cmake)
\ No newline at end of file
diff --git a/gpu.cmake b/gpu.cmake
index efccc2dcf6b8792f4b9e9d0e98242eba2db94b19..78d21ec9503a1684e8a9d811d8fd8f3568f9e6b8 100644
--- a/gpu.cmake
+++ b/gpu.cmake
@@ -11,17 +11,6 @@ endif()
 
 project(VirtualFluidsGPU)
 
-set(libraryFolder    "libs")
-set(gksLibraryFolder "libs/GKS")
-
-set(testFolder "tests")
-
-set(appFolder    "apps")
-set(lbmAppFolder "apps/LBM")
-set(gksAppFolder "apps/GKS")
-
-set(thirdPartyFolder "3rdParty")
-
 IF(MSVC)
     ADD_DEFINITIONS ( "-DNOMINMAX" )                # Disable Min/Max-Macros
     ADD_DEFINITIONS ( "-D_CRT_SECURE_NO_WARNINGS" ) # disable warnings promoting Microsoft's security enhanced CRT
diff --git a/src/basics/CMakeLists.txt b/src/basics/CMakeLists.txt
index e267ee03d7b8550d97196d9a2bb89e2146f7e00c..0b643212ad9c5da74e711d72da085c1fe670704e 100644
--- a/src/basics/CMakeLists.txt
+++ b/src/basics/CMakeLists.txt
@@ -21,6 +21,7 @@ IF(MSVC)
     target_compile_definitions(${library_name} PUBLIC NOMINMAX) # Disable Min/Max-Macros
 ENDIF(MSVC)
 
-include (${VF_CMAKE_DIR}/3rd/mpi.cmake)
+
+linkMPI()
 
 vf_add_tests()
\ No newline at end of file
diff --git a/src/basics/Core/Input/Input.h b/src/basics/Core/Input/Input.h
index 7adbc305f84f4a5cd8136e044c13a3b197277cab..9c95e2a167139b9ba3bab2937ed5d666ba1e1022 100644
--- a/src/basics/Core/Input/Input.h
+++ b/src/basics/Core/Input/Input.h
@@ -15,6 +15,8 @@ namespace input
 	public:
         static BASICS_EXPORT std::unique_ptr<Input> makeInput(std::istream &stream, const std::string &inputType);
 
+        virtual ~Input() = default;
+
         virtual bool hasValue(const std::string &key) const = 0;
         virtual std::string getValue(const std::string &key) = 0;
 	};
diff --git a/src/cpu/VirtualFluidsCore/CMakeLists.txt b/src/cpu/VirtualFluidsCore/CMakeLists.txt
index 02a6d775322ce0568b20e55fd86934e4e253429c..5ded9f35c0104d6584f2f21c99e2703b7730e927 100644
--- a/src/cpu/VirtualFluidsCore/CMakeLists.txt
+++ b/src/cpu/VirtualFluidsCore/CMakeLists.txt
@@ -1,10 +1,4 @@
 
-
-
-IF(${USE_FETOL})
-   # INCLUDE(${SOURCE_DIR}/VirtualFluidsCore/FETOL/CMakePackage.txt) TODO: Did not exists?
-ENDIF()
-
 IF(${USE_GCC})
    SET(CAB_ADDITIONAL_LINK_LIBRARIES ${CAB_ADDITIONAL_LINK_LIBRARIES} rt)
    SET(CAB_ADDITIONAL_LINK_LIBRARIES ${CAB_ADDITIONAL_LINK_LIBRARIES} gomp)
diff --git a/src/gpu/GksGpu/CMakeLists.txt b/src/gpu/GksGpu/CMakeLists.txt
index 67e536e988abac35e4cac76c0ed6605cd37321d7..353a5c8424f8c454d21e58b1acb405611414462c 100644
--- a/src/gpu/GksGpu/CMakeLists.txt
+++ b/src/gpu/GksGpu/CMakeLists.txt
@@ -1,6 +1,6 @@
 
-vf_add_library(BUILDTYPE static DEPENDS basics GksMeshAdapter)
+vf_add_library(BUILDTYPE shared DEPENDS basics GksMeshAdapter)
 
-include (${VF_CMAKE_DIR}/3rd/cuda.cmake)
-include (${VF_CMAKE_DIR}/3rd/mpi.cmake)
-include (${VF_CMAKE_DIR}/3rd/OpenMP.cmake)
+linkCUDA()
+linkMPI()
+linkOpenMP()
diff --git a/src/gpu/GksMeshAdapter/CMakeLists.txt b/src/gpu/GksMeshAdapter/CMakeLists.txt
index 6299f8deec9283f3530a016af70184cb3b95f437..7e008f0cef544e51fa1f474b60a18e3d8ca9cbc9 100644
--- a/src/gpu/GksMeshAdapter/CMakeLists.txt
+++ b/src/gpu/GksMeshAdapter/CMakeLists.txt
@@ -1,11 +1,3 @@
 
 
-vf_add_library(BUILDTYPE static DEPENDS basics GridGenerator)
-
-
-vf_get_library_name(library_name)
-target_include_directories(${library_name} PRIVATE "${CMAKE_SOURCE_DIR}/src/basics")
-target_include_directories(${library_name} PRIVATE "${CMAKE_SOURCE_DIR}/src/gpu")
-target_include_directories(${library_name} PRIVATE "${CMAKE_SOURCE_DIR}/src/gpu/GridGenerator")
-target_include_directories(${library_name} PRIVATE "${CMAKE_SOURCE_DIR}/src/basics/Core")
-
+vf_add_library(BUILDTYPE shared DEPENDS basics GridGenerator)
diff --git a/src/gpu/GridGenerator/CMakeLists.txt b/src/gpu/GridGenerator/CMakeLists.txt
index 4191490e82c49e7d21a3cae793040c010fd48f4e..86b49cc4712e4ec23df96ba5a9bfa912ee23029f 100644
--- a/src/gpu/GridGenerator/CMakeLists.txt
+++ b/src/gpu/GridGenerator/CMakeLists.txt
@@ -2,9 +2,7 @@
 
 vf_add_library(BUILDTYPE shared DEPENDS basics)
 
-include (${VF_CMAKE_DIR}/3rd/cuda.cmake)
-include (${VF_CMAKE_DIR}/3rd/OpenMP.cmake)
-
-vf_get_library_name(library_name)
+linkCUDA()
+linkOpenMP()
 
 set_property(TARGET ${library_name} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/CMakeLists.txt b/src/gpu/VirtualFluids_GPU/CMakeLists.txt
index 83806f18d0eaa4fa4bd0e3570f8772ea0712fba9..d24037e51bb922823625ce8a7605d581098681cb 100644
--- a/src/gpu/VirtualFluids_GPU/CMakeLists.txt
+++ b/src/gpu/VirtualFluids_GPU/CMakeLists.txt
@@ -9,10 +9,9 @@ ENDIF(MSVC)
 
 vf_add_library(BUILDTYPE shared DEPENDS ${libsToLink})
 
-include (${VF_CMAKE_DIR}/3rd/cuda.cmake)
-include (${VF_CMAKE_DIR}/3rd/mpi.cmake)
-include (${VF_CMAKE_DIR}/3rd/boost.cmake)
-linkBoost ("serialization")
+linkMPI()
+linkCUDA()
+linkBoost("serialization")
 
 #SET(TPN_WIN32 "/EHsc")
 #https://stackoverflow.com/questions/6832666/lnk2019-when-including-asio-headers-solution-generated-with-cmake