diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ebc1014c0de8ea73d20a323b09390344e585cf77..5c4740e1a01cf175bc4990b01ecd93ccecc3ec52 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,10 +3,15 @@ image: irmb/virtualfluids-python-deps
 stages:
   - build
   - test
+  - analyze
   - deploy
   - release
 
-build:
+
+###############################################################################
+##                                Builds                                     ##
+###############################################################################
+gcc_9_python:
   stage: build
 
   cache:
@@ -26,6 +31,115 @@ build:
   script:
     - python3 setup.py install
 
+gcc_9:
+  stage: build
+
+  tags:
+    - gpu
+    - linux
+
+  cache:
+    key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG-gcc9-hybrid"
+    paths:
+      - build_gcc9
+
+  artifacts:
+    paths:
+      - build_gcc9
+
+  before_script:
+    - export DEBIAN_FRONTEND=noninteractive
+    - apt-get update
+    - apt-get install -y libboost-serialization-dev
+    - cd /tmp
+    - apt-get install unzip
+    - wget https://github.com/NVIDIA/cuda-samples/archive/10.1.2.zip
+    - unzip 10.1.2.zip
+    - export NVCUDASAMPLES_ROOT=$(pwd)/cuda-samples-10.1.2
+
+  script:
+    - cd $CI_PROJECT_DIR
+    - mkdir -p build_gcc9
+    - cd build_gcc9
+    - cmake .. -DBUILD_VF_CPU=ON -DBUILD_VF_GPU=ON
+    - make -j4
+
+clang_10:
+  stage: build
+
+  tags:
+    - gpu
+    - linux
+
+  cache:
+    key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG-clang10-hybrid"
+    paths:
+      - build_clang10
+
+  artifacts:
+    paths:
+      - build_clang10
+
+  before_script:
+    - export DEBIAN_FRONTEND=noninteractive
+    - apt-get update
+    - export CC=clang
+    - export CXX=clang++
+    - $CXX --version
+    - apt-get install -y libboost-serialization-dev
+    - cd /tmp
+    - apt-get install unzip
+    - wget https://github.com/NVIDIA/cuda-samples/archive/10.1.2.zip
+    - unzip 10.1.2.zip
+    - export NVCUDASAMPLES_ROOT=$(pwd)/cuda-samples-10.1.2
+
+  script:
+    - cd $CI_PROJECT_DIR
+    - mkdir -p build_gcc9
+    - cd build_gcc9
+    - cmake .. -DBUILD_VF_CPU=ON -DBUILD_VF_GPU=ON
+    - make -j4
+
+msvc_16:
+  stage: build
+
+  tags:
+    - win
+    - gpu
+
+  variables:
+    CMAKE_GENERATOR: "Visual Studio 16 2019"
+    BUILD_CONFIGURATION: "Release"
+    BUILD_FOLDER: "build"
+    BUILD_VF_CPU: "ON"
+    BUILD_VF_GPU: "ON"
+    BUILD_VF_UNIT_TESTS: "ON"
+
+  # add cmake and MSBuild.exe to the path.
+  # This Needs to be adapted when moved to a new build machine.
+  before_script:
+    - git --version
+    - $env:Path += ";C:\Program Files\CMake\bin\"
+    - cmake --version
+    - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin"
+    - MSBuild.exe -version
+
+  script:
+    - cd $CI_PROJECT_DIR
+    - md -force $env:BUILD_FOLDER
+    - cd $env:BUILD_FOLDER
+    - cmake .. -DBUILD_VF_CPU=$env:BUILD_VF_CPU -DBUILD_VF_GPU=$env:BUILD_VF_GPU -DBUILD_VF_UNIT_TESTS=$env:BUILD_VF_UNIT_TESTS -G "$env:CMAKE_GENERATOR" ..
+    - MSBuild.exe VirtualFluids.sln /property:Configuration=$env:BUILD_CONFIGURATION /verbosity:minimal /maxcpucount:4
+
+  cache:
+    key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG-windows"
+    paths:
+      - $CI_PROJECT_DIR/$env:BUILD_FOLDER/
+
+  artifacts:
+    paths:
+      - $CI_PROJECT_DIR/$env:BUILD_FOLDER/
+
 
 build_singularity_image:
   stage: build
@@ -40,20 +154,40 @@ build_singularity_image:
     - singularity build Containers/VirtualFluidsOpenMPI.sif Containers/VirtualFluidsOpenMPI.def
     - ls -sh Containers/VirtualFluidsOpenMPI.sif
 
-
-virtual_fluids_basics_test:
+###############################################################################
+##                                Tests                                      ##
+###############################################################################
+gcc_9_python_unit_tests:
   stage: test
 
+  needs: ["gcc_9_python"]
+
   before_script:
     - export VF_UNITTESTS=$(find _skbuild -name basicsTests)
 
   script:
     - $VF_UNITTESTS
 
+msvc_16_unit_tests:
+  stage: test
+
+  tags:
+    - win
+    - gpu
+
+  needs: ["msvc_16"]
+
+  before_script:
+    - cd $CI_PROJECT_DIR/build
+
+  script:
+    - .\bin\Release\basicsTests.exe
 
-test_python_bindings:
+gcc_9_python_bindings_test:
   stage: test
 
+  needs: ["gcc_9_python"]
+
   artifacts:
     when: on_failure
     paths:
@@ -66,59 +200,17 @@ test_python_bindings:
   script:
     - python3 -m unittest discover -s Python -v
 
-deploy_to_phoenix:
-  stage: deploy
-  needs: ["build"]
-
-  before_script:
-    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
-    - apt-get install -y rsync
-    - mkdir -p ~/.ssh
-    - chmod 700 ~/.ssh
-    - eval $(ssh-agent -s)
-    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
-    - echo $SSH_PRIVATE_KEY >> ansible/private_key
-    - ssh-keyscan -t rsa phoenix.hlr.rz.tu-bs.de >> ~/.ssh/known_hosts
-    - pip3 install ansible
-
-  script:
-    - ansible-playbook -i ansible/hosts.cfg -u $REMOTE_USER ansible/playbook.yml
-
-  parallel:
-    matrix:
-      - ANSIBLE_MATRIX: 0
-        REMOTE_USER:
-          - y0054816
-
-create_release:
-  image: registry.gitlab.com/gitlab-org/release-cli:latest
-  stage: release
-  needs: ["build_singularity_image"]
-  rules:
-    - if: $CI_COMMIT_TAG
-
-  script:
-    - echo "Creating release with tag $CI_COMMIT_TAG"
-    - release-cli create --name "VirtualFluids $CI_COMMIT_TAG" \
-      --description "VirtualFluids CFD Simulator" \
-      --tag-name "$CI_COMMIT_TAG" \
-      --ref "$CI_COMMIT_SHA" \
-      --job-token "$CI_JOB_TOKEN" \
-      --assets-link="{'name':'VirtualFluidsSingularityImage_OpenMPI','url':'','type':'other','filepath':'Containers/VirtualFluidsOpenMPI.sif'}"
-    - build/bin/basicsTests
-
 
 ###############################################################################
-##                                                                           ##
-##    Deploy: Code analysis                                                  ##
-##                                                                           ##
+##                        Code analysis                                      ##
 ###############################################################################
-
-clangBuildAnalyzer:
-  stage: test
+clang_build_analyzer_clang_10:
+  stage: analyze
 
   only: ["schedules"]
 
+  needs: []
+
   before_script:
     - export DEBIAN_FRONTEND=noninteractive
     - apt-get update
@@ -135,7 +227,8 @@ clangBuildAnalyzer:
     - export PATH+=:$(pwd)
 
   script:
-    - mkdir $CI_PROJECT_DIR/build
+    - mkdir -p $CI_PROJECT_DIR/build
+    - rm -r ./*
     - cd $CI_PROJECT_DIR/build
     - cmake .. -DBUILD_VF_CPU=ON -DUSE_OPENMP=OFF -DCMAKE_CXX_FLAGS=-ftime-trace
     - ClangBuildAnalyzer --start .
@@ -144,11 +237,13 @@ clangBuildAnalyzer:
     - ClangBuildAnalyzer --analyze CBA
 
 
-include_what_you_use:
-  stage: test
+include_what_you_use_gcc_9:
+  stage: analyze
 
   only: ["schedules"]
 
+  needs: []
+
   before_script:
     - export DEBIAN_FRONTEND=noninteractive
     - apt-get update
@@ -161,14 +256,17 @@ include_what_you_use:
     - export PATH+=:$(pwd)/bin
 
   script:
-    - mkdir $CI_PROJECT_DIR/build
+    - mkdir -p $CI_PROJECT_DIR/build
+    - rm -r ./*
     - cd $CI_PROJECT_DIR/build
     - cmake .. -DBUILD_VF_CPU=ON -DUSE_OPENMP=OFF -DBUILD_VF_INCLUDE_WHAT_YOU_USE=ON
     - make
 
 
 cppcheck:
-  stage: test
+  stage: analyze
+
+  needs: []
 
   before_script:
     - export DEBIAN_FRONTEND=noninteractive
@@ -185,29 +283,12 @@ cppcheck:
     paths:
       - html_report/
 
-
-deploy_cppcheck_to_elladan:
-  stage: deploy
-  needs: ["cppcheck"]
-
-  before_script:
-    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
-    - apt-get install -y rsync
-    - mkdir -p ~/.ssh
-    - chmod 700 ~/.ssh
-    - eval $(ssh-agent -s)
-    - echo "$SSH_PRIVATE_KEY_ELLADAN" | tr -d '\r' | ssh-add -
-    - ssh-keyscan -t rsa elladan.irmb.bau.tu-bs.de >> ~/.ssh/known_hosts
-    - pip3 install ansible
-
-  script:
-    - ansible-playbook -i ansible/hosts.cfg -u public_pages ansible/playbook_cppcheck.yml
-
-
 # lizard - Cyclomatic Complexity Analyzer
 # Ignore warnings is manually set to 191. This job will fail when new warnings are added.
 lizard:
-  stage: test
+  stage: analyze
+
+  needs: []
 
   before_script:
     - export DEBIAN_FRONTEND=noninteractive
@@ -228,8 +309,10 @@ lizard:
       - lizard.txt
 
 # code coverage
-gcov:
-  stage: test
+gcov_gcc_9:
+  stage: analyze
+
+  needs: []
 
   before_script:
     - export DEBIAN_FRONTEND=noninteractive
@@ -267,10 +350,56 @@ gcov:
       - gcov_build/
 
 
-deploy_gcov_to_elladan:
+clang-tidy:
+  stage: analyze
+
+  before_script:
+    - run-clang-tidy -h
+
+  script:
+    - cd $CI_PROJECT_DIR
+    - mkdir -p build_clang_tidy
+    - cd build_clang_tidy
+    - cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_VF_CPU=ON -DBUILD_VF_GPU=OFF
+    - python3 ../utilities/filterCompileCommands.py compile_commands.json
+    - run-clang-tidy -quiet > clang-tidy-results.txt
+
+  artifacts:
+    paths:
+      - build_clang_tidy/clang-tidy-results.txt
+
+###############################################################################
+##                               Deploy                                      ##
+###############################################################################
+vf_to_phoenix:
   stage: deploy
+  
+  needs: ["gcc_9_python"]
 
-  needs: ["gcov"]
+  before_script:
+    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
+    - apt-get install -y rsync
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - eval $(ssh-agent -s)
+    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
+    - echo $SSH_PRIVATE_KEY >> ansible/private_key
+    - ssh-keyscan -t rsa phoenix.hlr.rz.tu-bs.de >> ~/.ssh/known_hosts
+    - pip3 install ansible
+
+  script:
+    - ansible-playbook -i ansible/hosts.cfg -u $REMOTE_USER ansible/playbook.yml
+
+  parallel:
+    matrix:
+      - ANSIBLE_MATRIX: 0
+        REMOTE_USER:
+          - y0054816
+
+
+cppcheck_to_elladan:
+  stage: deploy
+  needs: ["cppcheck"]
 
   before_script:
     - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
@@ -283,36 +412,44 @@ deploy_gcov_to_elladan:
     - pip3 install ansible
 
   script:
-    - ansible-playbook -i ansible/hosts.cfg -u public_pages ansible/playbook_gcov.yml
+    - ansible-playbook -i ansible/hosts.cfg -u public_pages ansible/playbook_cppcheck.yml
 
 
-# windows
-windows:
-  stage: build
+gcov_to_elladan:
+  stage: deploy
 
-  tags:
-    - windows10
+  needs: ["gcov_gcc_9"]
 
   before_script:
-    - git --version
-    - $env:Path += ";C:\Program Files\CMake\bin\"
-    - cmake --version
-    - $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin"
-    - MSBuild.exe -version
+    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
+    - apt-get install -y rsync
+    - mkdir -p ~/.ssh
+    - chmod 700 ~/.ssh
+    - eval $(ssh-agent -s)
+    - echo "$SSH_PRIVATE_KEY_ELLADAN" | tr -d '\r' | ssh-add -
+    - ssh-keyscan -t rsa elladan.irmb.bau.tu-bs.de >> ~/.ssh/known_hosts
+    - pip3 install ansible
 
   script:
-    - cd $CI_PROJECT_DIR
-    - md -force build
-    - cd build
-    - cmake .. -DBUILD_VF_CPU=OFF -DBUILD_VF_GPU=ON -DBUILD_VF_UNIT_TESTS=ON -G "$env:CMAKE_GENERATOR" ..
-    - MSBuild.exe VirtualFluids.sln /property:Configuration=$env:BUILD_CONFIGURATION /verbosity:minimal /maxcpucount:4
-    - . ".\bin\$env:BUILD_CONFIGURATION\basicsTests.exe"
+    - ansible-playbook -i ansible/hosts.cfg -u public_pages ansible/playbook_gcov.yml
 
-  variables:
-    CMAKE_GENERATOR: "Visual Studio 16 2019"
-    BUILD_CONFIGURATION: "Release"
 
-  cache:
-    key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG-windows"
-    paths:
-      - $CI_PROJECT_DIR/build/
+###############################################################################
+##                              Release                                      ##
+###############################################################################
+create_release:
+  image: registry.gitlab.com/gitlab-org/release-cli:latest
+  stage: release
+  needs: ["build_singularity_image"]
+  rules:
+    - if: $CI_COMMIT_TAG
+
+  script:
+    - echo "Creating release with tag $CI_COMMIT_TAG"
+    - release-cli create --name "VirtualFluids $CI_COMMIT_TAG" \
+      --description "VirtualFluids CFD Simulator" \
+      --tag-name "$CI_COMMIT_TAG" \
+      --ref "$CI_COMMIT_SHA" \
+      --job-token "$CI_JOB_TOKEN" \
+      --assets-link="{'name':'VirtualFluidsSingularityImage_OpenMPI','url':'','type':'other','filepath':'Containers/VirtualFluidsOpenMPI.sif'}"
+    - build/bin/basicsTests
\ No newline at end of file
diff --git a/utilities/filterCompileCommands.py b/utilities/filterCompileCommands.py
new file mode 100644
index 0000000000000000000000000000000000000000..999f5809b4e29f139a93d854f68171ac97b56b70
--- /dev/null
+++ b/utilities/filterCompileCommands.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+
+import json
+import sys
+
+
+def compile_command_selector(x):
+    return not ("3rdParty" in x["file"])
+
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print("usage: ./filterCompileCommands.py compile_commands.json")
+        exit(-1)
+
+    filename = sys.argv[1]
+    print("loading compile commands file: {}".format(filename))
+
+    fin = open(filename, "r")
+    cc = json.load(fin)
+    fin.close()
+
+    print("compile commands read: {}".format(len(cc)))
+
+    cc_filtered = list(filter(compile_command_selector, cc))
+
+    print("compile commands filtered: {}".format(len(cc_filtered)))
+
+    fout = open(filename, "w")
+    json.dump(cc_filtered, fout, indent=4)
+    fout.close()